Prefer DiagnosticBuilder over Diagnostic in diagnostic modifiers.

There are lots of functions that modify a diagnostic. This can be via a
`&mut Diagnostic` or a `&mut DiagnosticBuilder`, because the latter type
wraps the former and impls `DerefMut`.

This commit converts all the `&mut Diagnostic` occurrences to `&mut
DiagnosticBuilder`. This is a step towards greatly simplifying
`Diagnostic`. Some of the relevant function are made generic, because
they deal with both errors and warnings. No function bodies are changed,
because all the modifier methods are available on both `Diagnostic` and
`DiagnosticBuilder`.
This commit is contained in:
Nicholas Nethercote 2024-02-01 10:13:24 +11:00
parent d88ad9e6b7
commit a16dbd7339
10 changed files with 24 additions and 24 deletions

View File

@ -4,7 +4,7 @@
use clippy_utils::source::snippet; use clippy_utils::source::snippet;
use clippy_utils::sugg::Sugg; use clippy_utils::sugg::Sugg;
use clippy_utils::ty::{get_discriminant_value, is_isize_or_usize}; use clippy_utils::ty::{get_discriminant_value, is_isize_or_usize};
use rustc_errors::{Applicability, Diagnostic, SuggestionStyle}; use rustc_errors::{Applicability, DiagnosticBuilder, SuggestionStyle};
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::{BinOpKind, Expr, ExprKind}; use rustc_hir::{BinOpKind, Expr, ExprKind};
use rustc_lint::LateContext; use rustc_lint::LateContext;
@ -177,7 +177,7 @@ fn offer_suggestion(
expr: &Expr<'_>, expr: &Expr<'_>,
cast_expr: &Expr<'_>, cast_expr: &Expr<'_>,
cast_to_span: Span, cast_to_span: Span,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_, ()>,
) { ) {
let cast_to_snip = snippet(cx, cast_to_span, ".."); let cast_to_snip = snippet(cx, cast_to_span, "..");
let suggestion = if cast_to_snip == "_" { let suggestion = if cast_to_snip == "_" {

View File

@ -1,4 +1,4 @@
use rustc_errors::Diagnostic; use rustc_errors::DiagnosticBuilder;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_lint::{LateContext, LintContext}; use rustc_lint::{LateContext, LintContext};
use rustc_middle::lint::in_external_macro; use rustc_middle::lint::in_external_macro;
@ -135,7 +135,7 @@ fn check_result_large_err<'tcx>(cx: &LateContext<'tcx>, err_ty: Ty<'tcx>, hir_ty
RESULT_LARGE_ERR, RESULT_LARGE_ERR,
hir_ty_span, hir_ty_span,
"the `Err`-variant returned from this function is very large", "the `Err`-variant returned from this function is very large",
|diag: &mut Diagnostic| { |diag: &mut DiagnosticBuilder<'_, ()>| {
diag.span_label(hir_ty_span, format!("the `Err`-variant is at least {ty_size} bytes")); diag.span_label(hir_ty_span, format!("the `Err`-variant is at least {ty_size} bytes"));
diag.help(format!("try reducing the size of `{err_ty}`, for example by boxing large elements or replacing it with `Box<{err_ty}>`")); diag.help(format!("try reducing the size of `{err_ty}`, for example by boxing large elements or replacing it with `Box<{err_ty}>`"));
}, },

View File

@ -1,7 +1,7 @@
use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::ty::is_type_diagnostic_item;
use clippy_utils::{higher, SpanlessEq}; use clippy_utils::{higher, SpanlessEq};
use rustc_errors::Diagnostic; use rustc_errors::DiagnosticBuilder;
use rustc_hir::intravisit::{self as visit, Visitor}; use rustc_hir::intravisit::{self as visit, Visitor};
use rustc_hir::{Expr, ExprKind}; use rustc_hir::{Expr, ExprKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
@ -59,7 +59,7 @@ fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
arm_visit.visit_expr(if_else); arm_visit.visit_expr(if_else);
if let Some(arm_mutex) = arm_visit.found_mutex_if_same_as(op_mutex) { if let Some(arm_mutex) = arm_visit.found_mutex_if_same_as(op_mutex) {
let diag = |diag: &mut Diagnostic| { let diag = |diag: &mut DiagnosticBuilder<'_, ()>| {
diag.span_label( diag.span_label(
op_mutex.span, op_mutex.span,
"this Mutex will remain locked for the entire `if let`-block...", "this Mutex will remain locked for the entire `if let`-block...",

View File

@ -1,7 +1,7 @@
use std::borrow::Cow; use std::borrow::Cow;
use std::collections::BTreeMap; use std::collections::BTreeMap;
use rustc_errors::Diagnostic; use rustc_errors::DiagnosticBuilder;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::intravisit::{walk_body, walk_expr, walk_inf, walk_ty, Visitor}; use rustc_hir::intravisit::{walk_body, walk_expr, walk_inf, walk_ty, Visitor};
use rustc_hir::{Body, Expr, ExprKind, GenericArg, Item, ItemKind, QPath, TyKind}; use rustc_hir::{Body, Expr, ExprKind, GenericArg, Item, ItemKind, QPath, TyKind};
@ -65,7 +65,7 @@ fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
fn suggestion( fn suggestion(
cx: &LateContext<'_>, cx: &LateContext<'_>,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_, ()>,
generics_span: Span, generics_span: Span,
generics_suggestion_span: Span, generics_suggestion_span: Span,
target: &ImplicitHasherType<'_>, target: &ImplicitHasherType<'_>,

View File

@ -9,7 +9,7 @@
peel_blocks_with_stmt, MaybePath, peel_blocks_with_stmt, MaybePath,
}; };
use itertools::Itertools; use itertools::Itertools;
use rustc_errors::{Applicability, Diagnostic}; use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir::def::Res; use rustc_hir::def::Res;
use rustc_hir::{Arm, BinOpKind, Block, Expr, ExprKind, HirId, PatKind, PathSegment, PrimTy, QPath, StmtKind}; use rustc_hir::{Arm, BinOpKind, Block, Expr, ExprKind, HirId, PatKind, PathSegment, PrimTy, QPath, StmtKind};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
@ -163,7 +163,7 @@ fn emit_suggestion<'tcx>(cx: &LateContext<'tcx>, suggestion: &ClampSuggestion<'t
}; };
let suggestion = format!("{assignment}{input}.clamp({min}, {max}){semicolon}"); let suggestion = format!("{assignment}{input}.clamp({min}, {max}){semicolon}");
let msg = "clamp-like pattern without using clamp function"; let msg = "clamp-like pattern without using clamp function";
let lint_builder = |d: &mut Diagnostic| { let lint_builder = |d: &mut DiagnosticBuilder<'_, ()>| {
d.span_suggestion(*span, "replace with clamp", suggestion, Applicability::MaybeIncorrect); d.span_suggestion(*span, "replace with clamp", suggestion, Applicability::MaybeIncorrect);
if *is_float { if *is_float {
d.note("clamp will panic if max < min, min.is_nan(), or max.is_nan()") d.note("clamp will panic if max < min, min.is_nan(), or max.is_nan()")

View File

@ -2,7 +2,7 @@
use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::source::{indent_of, snippet}; use clippy_utils::source::{indent_of, snippet};
use clippy_utils::{get_attr, is_lint_allowed}; use clippy_utils::{get_attr, is_lint_allowed};
use rustc_errors::{Applicability, Diagnostic}; use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::intravisit::{walk_expr, Visitor};
use rustc_hir::{Arm, Expr, ExprKind, MatchSource}; use rustc_hir::{Arm, Expr, ExprKind, MatchSource};
use rustc_lint::{LateContext, LintContext}; use rustc_lint::{LateContext, LintContext};
@ -37,7 +37,7 @@ pub(super) fn check<'tcx>(
} }
} }
fn set_diagnostic<'tcx>(diag: &mut Diagnostic, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, found: FoundSigDrop) { fn set_diagnostic<'tcx>(diag: &mut DiagnosticBuilder<'_, ()>, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, found: FoundSigDrop) {
if found.lint_suggestion == LintSuggestion::MoveAndClone { if found.lint_suggestion == LintSuggestion::MoveAndClone {
// If our suggestion is to move and clone, then we want to leave it to the user to // If our suggestion is to move and clone, then we want to leave it to the user to
// decide how to address this lint, since it may be that cloning is inappropriate. // decide how to address this lint, since it may be that cloning is inappropriate.

View File

@ -1,6 +1,6 @@
use clippy_utils::diagnostics::span_lint_and_then; use clippy_utils::diagnostics::span_lint_and_then;
use clippy_utils::ty::is_type_diagnostic_item; use clippy_utils::ty::is_type_diagnostic_item;
use rustc_errors::{Applicability, Diagnostic}; use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_lint::LateContext; use rustc_lint::LateContext;
use rustc_span::{sym, Span}; use rustc_span::{sym, Span};
use {rustc_ast as ast, rustc_hir as hir}; use {rustc_ast as ast, rustc_hir as hir};
@ -22,7 +22,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, recv: &'tcx hir::Expr<'_>, arg
SUSPICIOUS_COMMAND_ARG_SPACE, SUSPICIOUS_COMMAND_ARG_SPACE,
arg.span, arg.span,
"single argument that looks like it should be multiple arguments", "single argument that looks like it should be multiple arguments",
|diag: &mut Diagnostic| { |diag: &mut DiagnosticBuilder<'_, ()>| {
diag.multipart_suggestion_verbose( diag.multipart_suggestion_verbose(
"consider splitting the argument", "consider splitting the argument",
vec![(span, "args".to_string()), (arg.span, format!("[{arg1:?}, {arg2:?}]"))], vec![(span, "args".to_string()), (arg.span, format!("[{arg1:?}, {arg2:?}]"))],

View File

@ -9,7 +9,7 @@
use rustc_ast::{LitKind, RangeLimits}; use rustc_ast::{LitKind, RangeLimits};
use rustc_data_structures::packed::Pu128; use rustc_data_structures::packed::Pu128;
use rustc_data_structures::unhash::UnhashMap; use rustc_data_structures::unhash::UnhashMap;
use rustc_errors::{Applicability, Diagnostic}; use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir::{BinOp, Block, Body, Expr, ExprKind, UnOp}; use rustc_hir::{BinOp, Block, Body, Expr, ExprKind, UnOp};
use rustc_lint::{LateContext, LateLintPass}; use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_lint_pass; use rustc_session::declare_lint_pass;
@ -67,7 +67,7 @@
fn report_lint<F>(cx: &LateContext<'_>, full_span: Span, msg: &str, indexes: &[Span], f: F) fn report_lint<F>(cx: &LateContext<'_>, full_span: Span, msg: &str, indexes: &[Span], f: F)
where where
F: FnOnce(&mut Diagnostic), F: FnOnce(&mut DiagnosticBuilder<'_, ()>),
{ {
span_lint_and_then(cx, MISSING_ASSERTS_FOR_INDEXING, full_span, msg, |diag| { span_lint_and_then(cx, MISSING_ASSERTS_FOR_INDEXING, full_span, msg, |diag| {
f(diag); f(diag);

View File

@ -6,7 +6,7 @@
implements_trait, implements_trait_with_env_from_iter, is_copy, is_type_diagnostic_item, is_type_lang_item, implements_trait, implements_trait_with_env_from_iter, is_copy, is_type_diagnostic_item, is_type_lang_item,
}; };
use rustc_ast::ast::Attribute; use rustc_ast::ast::Attribute;
use rustc_errors::{Applicability, Diagnostic}; use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir::intravisit::FnKind; use rustc_hir::intravisit::FnKind;
use rustc_hir::{ use rustc_hir::{
BindingAnnotation, Body, FnDecl, GenericArg, HirId, HirIdSet, Impl, ItemKind, LangItem, Mutability, Node, PatKind, BindingAnnotation, Body, FnDecl, GenericArg, HirId, HirIdSet, Impl, ItemKind, LangItem, Mutability, Node, PatKind,
@ -196,7 +196,7 @@ fn check_fn(
&& !moved_vars.contains(&canonical_id) && !moved_vars.contains(&canonical_id)
{ {
// Dereference suggestion // Dereference suggestion
let sugg = |diag: &mut Diagnostic| { let sugg = |diag: &mut DiagnosticBuilder<'_, ()>| {
if let ty::Adt(def, ..) = ty.kind() { if let ty::Adt(def, ..) = ty.kind() {
if let Some(span) = cx.tcx.hir().span_if_local(def.did()) { if let Some(span) = cx.tcx.hir().span_if_local(def.did()) {
if type_allowed_to_implement_copy( if type_allowed_to_implement_copy(

View File

@ -8,13 +8,13 @@
//! Thank you! //! Thank you!
//! ~The `INTERNAL_METADATA_COLLECTOR` lint //! ~The `INTERNAL_METADATA_COLLECTOR` lint
use rustc_errors::{Applicability, Diagnostic, MultiSpan}; use rustc_errors::{Applicability, DiagnosticBuilder, MultiSpan};
use rustc_hir::HirId; use rustc_hir::HirId;
use rustc_lint::{LateContext, Lint, LintContext}; use rustc_lint::{LateContext, Lint, LintContext};
use rustc_span::Span; use rustc_span::Span;
use std::env; use std::env;
fn docs_link(diag: &mut Diagnostic, lint: &'static Lint) { fn docs_link(diag: &mut DiagnosticBuilder<'_, ()>, lint: &'static Lint) {
if env::var("CLIPPY_DISABLE_DOCS_LINKS").is_err() { if env::var("CLIPPY_DISABLE_DOCS_LINKS").is_err() {
if let Some(lint) = lint.name_lower().strip_prefix("clippy::") { if let Some(lint) = lint.name_lower().strip_prefix("clippy::") {
diag.help(format!( diag.help(format!(
@ -143,7 +143,7 @@ pub fn span_lint_and_then<C, S, F>(cx: &C, lint: &'static Lint, sp: S, msg: &str
where where
C: LintContext, C: LintContext,
S: Into<MultiSpan>, S: Into<MultiSpan>,
F: FnOnce(&mut Diagnostic), F: FnOnce(&mut DiagnosticBuilder<'_, ()>),
{ {
#[expect(clippy::disallowed_methods)] #[expect(clippy::disallowed_methods)]
cx.span_lint(lint, sp, msg.to_string(), |diag| { cx.span_lint(lint, sp, msg.to_string(), |diag| {
@ -165,7 +165,7 @@ pub fn span_lint_hir_and_then(
hir_id: HirId, hir_id: HirId,
sp: impl Into<MultiSpan>, sp: impl Into<MultiSpan>,
msg: &str, msg: &str,
f: impl FnOnce(&mut Diagnostic), f: impl FnOnce(&mut DiagnosticBuilder<'_, ()>),
) { ) {
#[expect(clippy::disallowed_methods)] #[expect(clippy::disallowed_methods)]
cx.tcx.node_span_lint(lint, hir_id, sp, msg.to_string(), |diag| { cx.tcx.node_span_lint(lint, hir_id, sp, msg.to_string(), |diag| {
@ -214,7 +214,7 @@ pub fn span_lint_and_sugg<T: LintContext>(
/// appear once per /// appear once per
/// replacement. In human-readable format though, it only appears once before /// replacement. In human-readable format though, it only appears once before
/// the whole suggestion. /// the whole suggestion.
pub fn multispan_sugg<I>(diag: &mut Diagnostic, help_msg: &str, sugg: I) pub fn multispan_sugg<I>(diag: &mut DiagnosticBuilder<'_, ()>, help_msg: &str, sugg: I)
where where
I: IntoIterator<Item = (Span, String)>, I: IntoIterator<Item = (Span, String)>,
{ {
@ -227,7 +227,7 @@ pub fn multispan_sugg<I>(diag: &mut Diagnostic, help_msg: &str, sugg: I)
/// multiple spans. This is tracked in issue [rustfix#141](https://github.com/rust-lang/rustfix/issues/141). /// multiple spans. This is tracked in issue [rustfix#141](https://github.com/rust-lang/rustfix/issues/141).
/// Suggestions with multiple spans will be silently ignored. /// Suggestions with multiple spans will be silently ignored.
pub fn multispan_sugg_with_applicability<I>( pub fn multispan_sugg_with_applicability<I>(
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_, ()>,
help_msg: &str, help_msg: &str,
applicability: Applicability, applicability: Applicability,
sugg: I, sugg: I,