1
Fork 0

Auto merge of #120576 - nnethercote:merge-Diagnostic-DiagnosticBuilder, r=davidtwco

Overhaul `Diagnostic` and `DiagnosticBuilder`

Implements the first part of https://github.com/rust-lang/compiler-team/issues/722, which moves functionality and use away from `Diagnostic`, onto `DiagnosticBuilder`.

Likely follow-ups:
- Move things around, because this PR was written to minimize diff size, so some things end up in sub-optimal places. E.g. `DiagnosticBuilder` has impls in both `diagnostic.rs` and `diagnostic_builder.rs`.
- Rename `Diagnostic` as `DiagInner` and `DiagnosticBuilder` as `Diag`.

r? `@davidtwco`
This commit is contained in:
bors 2024-02-20 12:05:09 +00:00
commit 29f87ade9d
104 changed files with 1038 additions and 849 deletions

View file

@ -1,5 +1,6 @@
use rustc_errors::{ use rustc_errors::{
codes::*, AddToDiagnostic, Diagnostic, DiagnosticArgFromDisplay, SubdiagnosticMessageOp, codes::*, AddToDiagnostic, DiagnosticArgFromDisplay, DiagnosticBuilder, EmissionGuarantee,
SubdiagnosticMessageOp,
}; };
use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{symbol::Ident, Span, Symbol}; use rustc_span::{symbol::Ident, Span, Symbol};
@ -41,7 +42,11 @@ pub struct InvalidAbi {
pub struct InvalidAbiReason(pub &'static str); pub struct InvalidAbiReason(pub &'static str);
impl AddToDiagnostic for InvalidAbiReason { impl AddToDiagnostic for InvalidAbiReason {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_: F,
) {
#[allow(rustc::untranslatable_diagnostic)] #[allow(rustc::untranslatable_diagnostic)]
diag.note(self.0); diag.note(self.0);
} }

View file

@ -1,7 +1,10 @@
//! Errors emitted by ast_passes. //! Errors emitted by ast_passes.
use rustc_ast::ParamKindOrd; use rustc_ast::ParamKindOrd;
use rustc_errors::{codes::*, AddToDiagnostic, Applicability, Diagnostic, SubdiagnosticMessageOp}; use rustc_errors::{
codes::*, AddToDiagnostic, Applicability, DiagnosticBuilder, EmissionGuarantee,
SubdiagnosticMessageOp,
};
use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{symbol::Ident, Span, Symbol}; use rustc_span::{symbol::Ident, Span, Symbol};
@ -372,7 +375,11 @@ pub struct EmptyLabelManySpans(pub Vec<Span>);
// The derive for `Vec<Span>` does multiple calls to `span_label`, adding commas between each // The derive for `Vec<Span>` does multiple calls to `span_label`, adding commas between each
impl AddToDiagnostic for EmptyLabelManySpans { impl AddToDiagnostic for EmptyLabelManySpans {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_: F,
) {
diag.span_labels(self.0, ""); diag.span_labels(self.0, "");
} }
} }
@ -729,7 +736,11 @@ pub struct StableFeature {
} }
impl AddToDiagnostic for StableFeature { impl AddToDiagnostic for StableFeature {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_: F,
) {
diag.arg("name", self.name); diag.arg("name", self.name);
diag.arg("since", self.since); diag.arg("since", self.since);
diag.help(fluent::ast_passes_stable_since); diag.help(fluent::ast_passes_stable_since);

View file

@ -22,6 +22,9 @@ macro_rules! gate {
}}; }};
($visitor:expr, $feature:ident, $span:expr, $explain:expr, $help:expr) => {{ ($visitor:expr, $feature:ident, $span:expr, $explain:expr, $help:expr) => {{
if !$visitor.features.$feature && !$span.allows_unstable(sym::$feature) { if !$visitor.features.$feature && !$span.allows_unstable(sym::$feature) {
// FIXME: make this translatable
#[allow(rustc::diagnostic_outside_of_impl)]
#[allow(rustc::untranslatable_diagnostic)]
feature_err(&$visitor.sess, sym::$feature, $span, $explain).with_help($help).emit(); feature_err(&$visitor.sess, sym::$feature, $span, $explain).with_help($help).emit();
} }
}}; }};

View file

@ -6,9 +6,7 @@
use either::Either; use either::Either;
use rustc_data_structures::captures::Captures; use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{ use rustc_errors::{codes::*, struct_span_code_err, Applicability, DiagnosticBuilder, MultiSpan};
codes::*, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan,
};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_hir::intravisit::{walk_block, walk_expr, Visitor}; use rustc_hir::intravisit::{walk_block, walk_expr, Visitor};
@ -635,7 +633,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
fn suggest_assign_value( fn suggest_assign_value(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
moved_place: PlaceRef<'tcx>, moved_place: PlaceRef<'tcx>,
sugg_span: Span, sugg_span: Span,
) { ) {
@ -674,7 +672,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
fn suggest_borrow_fn_like( fn suggest_borrow_fn_like(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
move_sites: &[MoveSite], move_sites: &[MoveSite],
value_name: &str, value_name: &str,
@ -742,7 +740,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
fn suggest_cloning( fn suggest_cloning(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
span: Span, span: Span,
@ -778,7 +776,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} }
} }
fn suggest_adding_copy_bounds(&self, err: &mut Diagnostic, ty: Ty<'tcx>, span: Span) { fn suggest_adding_copy_bounds(
&self,
err: &mut DiagnosticBuilder<'_>,
ty: Ty<'tcx>,
span: Span,
) {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
let generics = tcx.generics_of(self.mir_def_id()); let generics = tcx.generics_of(self.mir_def_id());
@ -1225,7 +1228,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
#[instrument(level = "debug", skip(self, err))] #[instrument(level = "debug", skip(self, err))]
fn suggest_using_local_if_applicable( fn suggest_using_local_if_applicable(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
location: Location, location: Location,
issued_borrow: &BorrowData<'tcx>, issued_borrow: &BorrowData<'tcx>,
explanation: BorrowExplanation<'tcx>, explanation: BorrowExplanation<'tcx>,
@ -1321,7 +1324,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
fn suggest_slice_method_if_applicable( fn suggest_slice_method_if_applicable(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
place: Place<'tcx>, place: Place<'tcx>,
borrowed_place: Place<'tcx>, borrowed_place: Place<'tcx>,
) { ) {
@ -1430,7 +1433,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
/// ``` /// ```
pub(crate) fn explain_iterator_advancement_in_for_loop_if_applicable( pub(crate) fn explain_iterator_advancement_in_for_loop_if_applicable(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
span: Span, span: Span,
issued_spans: &UseSpans<'tcx>, issued_spans: &UseSpans<'tcx>,
) { ) {
@ -1617,7 +1620,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
/// ``` /// ```
fn suggest_using_closure_argument_instead_of_capture( fn suggest_using_closure_argument_instead_of_capture(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
borrowed_place: Place<'tcx>, borrowed_place: Place<'tcx>,
issued_spans: &UseSpans<'tcx>, issued_spans: &UseSpans<'tcx>,
) { ) {
@ -1751,7 +1754,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
fn suggest_binding_for_closure_capture_self( fn suggest_binding_for_closure_capture_self(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
issued_spans: &UseSpans<'tcx>, issued_spans: &UseSpans<'tcx>,
) { ) {
let UseSpans::ClosureUse { capture_kind_span, .. } = issued_spans else { return }; let UseSpans::ClosureUse { capture_kind_span, .. } = issued_spans else { return };
@ -2997,7 +3000,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
self.buffer_error(err); self.buffer_error(err);
} }
fn explain_deref_coercion(&mut self, loan: &BorrowData<'tcx>, err: &mut Diagnostic) { fn explain_deref_coercion(&mut self, loan: &BorrowData<'tcx>, err: &mut DiagnosticBuilder<'_>) {
let tcx = self.infcx.tcx; let tcx = self.infcx.tcx;
if let ( if let (
Some(Terminator { Some(Terminator {
@ -3532,7 +3535,11 @@ enum AnnotatedBorrowFnSignature<'tcx> {
impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { impl<'tcx> AnnotatedBorrowFnSignature<'tcx> {
/// Annotate the provided diagnostic with information about borrow from the fn signature that /// Annotate the provided diagnostic with information about borrow from the fn signature that
/// helps explain. /// helps explain.
pub(crate) fn emit(&self, cx: &mut MirBorrowckCtxt<'_, 'tcx>, diag: &mut Diagnostic) -> String { pub(crate) fn emit(
&self,
cx: &mut MirBorrowckCtxt<'_, 'tcx>,
diag: &mut DiagnosticBuilder<'_>,
) -> String {
match self { match self {
&AnnotatedBorrowFnSignature::Closure { argument_ty, argument_span } => { &AnnotatedBorrowFnSignature::Closure { argument_ty, argument_span } => {
diag.span_label( diag.span_label(

View file

@ -3,7 +3,7 @@
#![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)] #![allow(rustc::untranslatable_diagnostic)]
use rustc_errors::{Applicability, Diagnostic}; use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
use rustc_index::IndexSlice; use rustc_index::IndexSlice;
@ -65,7 +65,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
body: &Body<'tcx>, body: &Body<'tcx>,
local_names: &IndexSlice<Local, Option<Symbol>>, local_names: &IndexSlice<Local, Option<Symbol>>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
borrow_desc: &str, borrow_desc: &str,
borrow_span: Option<Span>, borrow_span: Option<Span>,
multiple_borrow_span: Option<(Span, Span)>, multiple_borrow_span: Option<(Span, Span)>,
@ -306,7 +306,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
fn add_object_lifetime_default_note( fn add_object_lifetime_default_note(
&self, &self,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
unsize_ty: Ty<'tcx>, unsize_ty: Ty<'tcx>,
) { ) {
if let ty::Adt(def, args) = unsize_ty.kind() { if let ty::Adt(def, args) = unsize_ty.kind() {
@ -359,7 +359,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
fn add_lifetime_bound_suggestion_to_diagnostic( fn add_lifetime_bound_suggestion_to_diagnostic(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
category: &ConstraintCategory<'tcx>, category: &ConstraintCategory<'tcx>,
span: Span, span: Span,
region_name: &RegionName, region_name: &RegionName,

View file

@ -5,7 +5,7 @@ use crate::session_diagnostics::{
CaptureVarKind, CaptureVarPathUseCause, OnClosureNote, CaptureVarKind, CaptureVarPathUseCause, OnClosureNote,
}; };
use itertools::Itertools; use itertools::Itertools;
use rustc_errors::{Applicability, Diagnostic}; use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{CtorKind, Namespace}; use rustc_hir::def::{CtorKind, Namespace};
use rustc_hir::CoroutineKind; use rustc_hir::CoroutineKind;
@ -80,7 +80,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
&self, &self,
location: Location, location: Location,
place: PlaceRef<'tcx>, place: PlaceRef<'tcx>,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
) -> bool { ) -> bool {
debug!("add_moved_or_invoked_closure_note: location={:?} place={:?}", location, place); debug!("add_moved_or_invoked_closure_note: location={:?} place={:?}", location, place);
let mut target = place.local_or_deref_local(); let mut target = place.local_or_deref_local();
@ -588,7 +588,7 @@ impl UseSpans<'_> {
pub(super) fn args_subdiag( pub(super) fn args_subdiag(
self, self,
dcx: &rustc_errors::DiagCtxt, dcx: &rustc_errors::DiagCtxt,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
f: impl FnOnce(Span) -> CaptureArgLabel, f: impl FnOnce(Span) -> CaptureArgLabel,
) { ) {
if let UseSpans::ClosureUse { args_span, .. } = self { if let UseSpans::ClosureUse { args_span, .. } = self {
@ -601,7 +601,7 @@ impl UseSpans<'_> {
pub(super) fn var_path_only_subdiag( pub(super) fn var_path_only_subdiag(
self, self,
dcx: &rustc_errors::DiagCtxt, dcx: &rustc_errors::DiagCtxt,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
action: crate::InitializationRequiringAction, action: crate::InitializationRequiringAction,
) { ) {
use crate::InitializationRequiringAction::*; use crate::InitializationRequiringAction::*;
@ -638,7 +638,7 @@ impl UseSpans<'_> {
pub(super) fn var_subdiag( pub(super) fn var_subdiag(
self, self,
dcx: &rustc_errors::DiagCtxt, dcx: &rustc_errors::DiagCtxt,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
kind: Option<rustc_middle::mir::BorrowKind>, kind: Option<rustc_middle::mir::BorrowKind>,
f: impl FnOnce(hir::ClosureKind, Span) -> CaptureVarCause, f: impl FnOnce(hir::ClosureKind, Span) -> CaptureVarCause,
) { ) {
@ -1010,7 +1010,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
fn explain_captures( fn explain_captures(
&mut self, &mut self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
span: Span, span: Span,
move_span: Span, move_span: Span,
move_spans: UseSpans<'tcx>, move_spans: UseSpans<'tcx>,

View file

@ -1,7 +1,7 @@
#![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)] #![allow(rustc::untranslatable_diagnostic)]
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder}; use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_middle::mir::*; use rustc_middle::mir::*;
use rustc_middle::ty::{self, Ty}; use rustc_middle::ty::{self, Ty};
use rustc_mir_dataflow::move_paths::{LookupResult, MovePathIndex}; use rustc_mir_dataflow::move_paths::{LookupResult, MovePathIndex};
@ -437,7 +437,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
err err
} }
fn add_move_hints(&self, error: GroupedMoveError<'tcx>, err: &mut Diagnostic, span: Span) { fn add_move_hints(
&self,
error: GroupedMoveError<'tcx>,
err: &mut DiagnosticBuilder<'_>,
span: Span,
) {
match error { match error {
GroupedMoveError::MovesFromPlace { mut binds_to, move_from, .. } => { GroupedMoveError::MovesFromPlace { mut binds_to, move_from, .. } => {
self.add_borrow_suggestions(err, span); self.add_borrow_suggestions(err, span);
@ -500,7 +505,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
} }
} }
fn add_borrow_suggestions(&self, err: &mut Diagnostic, span: Span) { fn add_borrow_suggestions(&self, err: &mut DiagnosticBuilder<'_>, span: Span) {
match self.infcx.tcx.sess.source_map().span_to_snippet(span) { match self.infcx.tcx.sess.source_map().span_to_snippet(span) {
Ok(snippet) if snippet.starts_with('*') => { Ok(snippet) if snippet.starts_with('*') => {
err.span_suggestion_verbose( err.span_suggestion_verbose(
@ -521,7 +526,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
} }
} }
fn add_move_error_suggestions(&self, err: &mut Diagnostic, binds_to: &[Local]) { fn add_move_error_suggestions(&self, err: &mut DiagnosticBuilder<'_>, binds_to: &[Local]) {
let mut suggestions: Vec<(Span, String, String)> = Vec::new(); let mut suggestions: Vec<(Span, String, String)> = Vec::new();
for local in binds_to { for local in binds_to {
let bind_to = &self.body.local_decls[*local]; let bind_to = &self.body.local_decls[*local];
@ -573,7 +578,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
} }
} }
fn add_move_error_details(&self, err: &mut Diagnostic, binds_to: &[Local]) { fn add_move_error_details(&self, err: &mut DiagnosticBuilder<'_>, binds_to: &[Local]) {
for (j, local) in binds_to.iter().enumerate() { for (j, local) in binds_to.iter().enumerate() {
let bind_to = &self.body.local_decls[*local]; let bind_to = &self.body.local_decls[*local];
let binding_span = bind_to.source_info.span; let binding_span = bind_to.source_info.span;
@ -610,7 +615,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
/// expansion of a packed struct. /// expansion of a packed struct.
/// Such errors happen because derive macro expansions shy away from taking /// Such errors happen because derive macro expansions shy away from taking
/// references to the struct's fields since doing so would be undefined behaviour /// references to the struct's fields since doing so would be undefined behaviour
fn add_note_for_packed_struct_derive(&self, err: &mut Diagnostic, local: Local) { fn add_note_for_packed_struct_derive(&self, err: &mut DiagnosticBuilder<'_>, local: Local) {
let local_place: PlaceRef<'tcx> = local.into(); let local_place: PlaceRef<'tcx> = local.into();
let local_ty = local_place.ty(self.body.local_decls(), self.infcx.tcx).ty.peel_refs(); let local_ty = local_place.ty(self.body.local_decls(), self.infcx.tcx).ty.peel_refs();

View file

@ -2,7 +2,7 @@
#![allow(rustc::untranslatable_diagnostic)] #![allow(rustc::untranslatable_diagnostic)]
use hir::ExprKind; use hir::ExprKind;
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder}; use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
use rustc_hir::Node; use rustc_hir::Node;
@ -540,7 +540,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
} }
} }
fn suggest_map_index_mut_alternatives(&self, ty: Ty<'tcx>, err: &mut Diagnostic, span: Span) { fn suggest_map_index_mut_alternatives(
&self,
ty: Ty<'tcx>,
err: &mut DiagnosticBuilder<'tcx>,
span: Span,
) {
let Some(adt) = ty.ty_adt_def() else { return }; let Some(adt) = ty.ty_adt_def() else { return };
let did = adt.did(); let did = adt.did();
if self.infcx.tcx.is_diagnostic_item(sym::HashMap, did) if self.infcx.tcx.is_diagnostic_item(sym::HashMap, did)
@ -548,7 +553,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
{ {
struct V<'a, 'tcx> { struct V<'a, 'tcx> {
assign_span: Span, assign_span: Span,
err: &'a mut Diagnostic, err: &'a mut DiagnosticBuilder<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
suggested: bool, suggested: bool,
} }
@ -790,7 +795,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
closure_local_def_id: hir::def_id::LocalDefId, closure_local_def_id: hir::def_id::LocalDefId,
the_place_err: PlaceRef<'tcx>, the_place_err: PlaceRef<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
) { ) {
let tables = tcx.typeck(closure_local_def_id); let tables = tcx.typeck(closure_local_def_id);
if let Some((span, closure_kind_origin)) = tcx.closure_kind_origin(closure_local_def_id) { if let Some((span, closure_kind_origin)) = tcx.closure_kind_origin(closure_local_def_id) {
@ -852,7 +857,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
// Attempt to search similar mutable associated items for suggestion. // Attempt to search similar mutable associated items for suggestion.
// In the future, attempt in all path but initially for RHS of for_loop // In the future, attempt in all path but initially for RHS of for_loop
fn suggest_similar_mut_method_for_for_loop(&self, err: &mut Diagnostic, span: Span) { fn suggest_similar_mut_method_for_for_loop(&self, err: &mut DiagnosticBuilder<'_>, span: Span) {
use hir::{ use hir::{
BorrowKind, Expr, BorrowKind, Expr,
ExprKind::{AddrOf, Block, Call, MethodCall}, ExprKind::{AddrOf, Block, Call, MethodCall},
@ -936,7 +941,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
} }
/// Targeted error when encountering an `FnMut` closure where an `Fn` closure was expected. /// Targeted error when encountering an `FnMut` closure where an `Fn` closure was expected.
fn expected_fn_found_fn_mut_call(&self, err: &mut Diagnostic, sp: Span, act: &str) { fn expected_fn_found_fn_mut_call(&self, err: &mut DiagnosticBuilder<'_>, sp: Span, act: &str) {
err.span_label(sp, format!("cannot {act}")); err.span_label(sp, format!("cannot {act}"));
let hir = self.infcx.tcx.hir(); let hir = self.infcx.tcx.hir();

View file

@ -5,7 +5,7 @@
#![allow(rustc::untranslatable_diagnostic)] #![allow(rustc::untranslatable_diagnostic)]
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::Diagnostic; use rustc_errors::DiagnosticBuilder;
use rustc_middle::ty::RegionVid; use rustc_middle::ty::RegionVid;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::collections::BTreeMap; use std::collections::BTreeMap;
@ -158,13 +158,13 @@ impl OutlivesSuggestionBuilder {
self.constraints_to_add.entry(fr).or_default().push(outlived_fr); self.constraints_to_add.entry(fr).or_default().push(outlived_fr);
} }
/// Emit an intermediate note on the given `Diagnostic` if the involved regions are /// Emit an intermediate note on the given `DiagnosticBuilder` if the involved regions are
/// suggestable. /// suggestable.
pub(crate) fn intermediate_suggestion( pub(crate) fn intermediate_suggestion(
&mut self, &mut self,
mbcx: &MirBorrowckCtxt<'_, '_>, mbcx: &MirBorrowckCtxt<'_, '_>,
errci: &ErrorConstraintInfo<'_>, errci: &ErrorConstraintInfo<'_>,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
) { ) {
// Emit an intermediate note. // Emit an intermediate note.
let fr_name = self.region_vid_to_name(mbcx, errci.fr); let fr_name = self.region_vid_to_name(mbcx, errci.fr);

View file

@ -1,7 +1,7 @@
//! Error reporting machinery for lifetime errors. //! Error reporting machinery for lifetime errors.
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, MultiSpan}; use rustc_errors::{Applicability, DiagnosticBuilder, MultiSpan};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::Res::Def; use rustc_hir::def::Res::Def;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
@ -251,6 +251,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
hrtb_bounds.iter().for_each(|bound| { hrtb_bounds.iter().for_each(|bound| {
let Trait(PolyTraitRef { trait_ref, span: trait_span, .. }, _) = bound else { return; }; let Trait(PolyTraitRef { trait_ref, span: trait_span, .. }, _) = bound else { return; };
// FIXME: make this translatable
#[allow(rustc::diagnostic_outside_of_impl)]
#[allow(rustc::untranslatable_diagnostic)]
diag.span_note( diag.span_note(
*trait_span, *trait_span,
"due to current limitations in the borrow checker, this implies a `'static` lifetime" "due to current limitations in the borrow checker, this implies a `'static` lifetime"
@ -421,6 +424,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
/// ``` /// ```
/// ///
/// Here we would be invoked with `fr = 'a` and `outlived_fr = 'b`. /// Here we would be invoked with `fr = 'a` and `outlived_fr = 'b`.
// FIXME: make this translatable
#[allow(rustc::diagnostic_outside_of_impl)]
#[allow(rustc::untranslatable_diagnostic)]
pub(crate) fn report_region_error( pub(crate) fn report_region_error(
&mut self, &mut self,
fr: RegionVid, fr: RegionVid,
@ -685,12 +691,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
borrowck_errors::borrowed_data_escapes_closure(self.infcx.tcx, *span, escapes_from); borrowck_errors::borrowed_data_escapes_closure(self.infcx.tcx, *span, escapes_from);
if let Some((Some(outlived_fr_name), outlived_fr_span)) = outlived_fr_name_and_span { if let Some((Some(outlived_fr_name), outlived_fr_span)) = outlived_fr_name_and_span {
// FIXME: make this translatable
#[allow(rustc::diagnostic_outside_of_impl)]
#[allow(rustc::untranslatable_diagnostic)]
diag.span_label( diag.span_label(
outlived_fr_span, outlived_fr_span,
format!("`{outlived_fr_name}` declared here, outside of the {escapes_from} body",), format!("`{outlived_fr_name}` declared here, outside of the {escapes_from} body",),
); );
} }
// FIXME: make this translatable
#[allow(rustc::diagnostic_outside_of_impl)]
#[allow(rustc::untranslatable_diagnostic)]
if let Some((Some(fr_name), fr_span)) = fr_name_and_span { if let Some((Some(fr_name), fr_span)) = fr_name_and_span {
diag.span_label( diag.span_label(
fr_span, fr_span,
@ -714,6 +726,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let outlived_fr_region_name = self.give_region_a_name(errci.outlived_fr).unwrap(); let outlived_fr_region_name = self.give_region_a_name(errci.outlived_fr).unwrap();
outlived_fr_region_name.highlight_region_name(&mut diag); outlived_fr_region_name.highlight_region_name(&mut diag);
// FIXME: make this translatable
#[allow(rustc::diagnostic_outside_of_impl)]
#[allow(rustc::untranslatable_diagnostic)]
diag.span_label( diag.span_label(
*span, *span,
format!( format!(
@ -808,7 +823,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
/// ``` /// ```
fn add_static_impl_trait_suggestion( fn add_static_impl_trait_suggestion(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
fr: RegionVid, fr: RegionVid,
// We need to pass `fr_name` - computing it again will label it twice. // We need to pass `fr_name` - computing it again will label it twice.
fr_name: RegionName, fr_name: RegionName,
@ -897,7 +912,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
fn maybe_suggest_constrain_dyn_trait_impl( fn maybe_suggest_constrain_dyn_trait_impl(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
f: Region<'tcx>, f: Region<'tcx>,
o: Region<'tcx>, o: Region<'tcx>,
category: &ConstraintCategory<'tcx>, category: &ConstraintCategory<'tcx>,
@ -959,7 +974,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
#[instrument(skip(self, err), level = "debug")] #[instrument(skip(self, err), level = "debug")]
fn suggest_constrain_dyn_trait_in_impl( fn suggest_constrain_dyn_trait_in_impl(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
found_dids: &FxIndexSet<DefId>, found_dids: &FxIndexSet<DefId>,
ident: Ident, ident: Ident,
self_ty: &hir::Ty<'_>, self_ty: &hir::Ty<'_>,
@ -994,7 +1009,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
fn suggest_adding_lifetime_params( fn suggest_adding_lifetime_params(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
sub: RegionVid, sub: RegionVid,
sup: RegionVid, sup: RegionVid,
) { ) {
@ -1023,7 +1038,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
suggest_adding_lifetime_params(self.infcx.tcx, sub, ty_sup, ty_sub, diag); suggest_adding_lifetime_params(self.infcx.tcx, sub, ty_sup, ty_sub, diag);
} }
fn suggest_move_on_borrowing_closure(&self, diag: &mut Diagnostic) { fn suggest_move_on_borrowing_closure(&self, diag: &mut DiagnosticBuilder<'_>) {
let map = self.infcx.tcx.hir(); let map = self.infcx.tcx.hir();
let body_id = map.body_owned_by(self.mir_def_id()); let body_id = map.body_owned_by(self.mir_def_id());
let expr = &map.body(body_id).value.peel_blocks(); let expr = &map.body(body_id).value.peel_blocks();

View file

@ -5,7 +5,7 @@ use std::fmt::{self, Display};
use std::iter; use std::iter;
use rustc_data_structures::fx::IndexEntry; use rustc_data_structures::fx::IndexEntry;
use rustc_errors::Diagnostic; use rustc_errors::DiagnosticBuilder;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_middle::ty::print::RegionHighlightMode; use rustc_middle::ty::print::RegionHighlightMode;
@ -106,7 +106,7 @@ impl RegionName {
} }
} }
pub(crate) fn highlight_region_name(&self, diag: &mut Diagnostic) { pub(crate) fn highlight_region_name(&self, diag: &mut DiagnosticBuilder<'_>) {
match &self.source { match &self.source {
RegionNameSource::NamedLateParamRegion(span) RegionNameSource::NamedLateParamRegion(span)
| RegionNameSource::NamedEarlyParamRegion(span) => { | RegionNameSource::NamedEarlyParamRegion(span) => {

View file

@ -2497,6 +2497,8 @@ mod diags {
} }
for (_, (mut diag, count)) in std::mem::take(&mut self.diags.buffered_mut_errors) { for (_, (mut diag, count)) in std::mem::take(&mut self.diags.buffered_mut_errors) {
if count > 10 { if count > 10 {
#[allow(rustc::diagnostic_outside_of_impl)]
#[allow(rustc::untranslatable_diagnostic)]
diag.note(format!("...and {} other attempted mutable borrows", count - 10)); diag.note(format!("...and {} other attempted mutable borrows", count - 10));
} }
self.diags.buffered_diags.push(BufferedDiag::Error(diag)); self.diags.buffered_diags.push(BufferedDiag::Error(diag));

View file

@ -5,7 +5,7 @@ use rustc_data_structures::binary_search_util;
use rustc_data_structures::frozen::Frozen; use rustc_data_structures::frozen::Frozen;
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::graph::scc::Sccs; use rustc_data_structures::graph::scc::Sccs;
use rustc_errors::Diagnostic; use rustc_errors::DiagnosticBuilder;
use rustc_hir::def_id::CRATE_DEF_ID; use rustc_hir::def_id::CRATE_DEF_ID;
use rustc_index::{IndexSlice, IndexVec}; use rustc_index::{IndexSlice, IndexVec};
use rustc_infer::infer::outlives::test_type_match; use rustc_infer::infer::outlives::test_type_match;
@ -592,7 +592,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
} }
/// Adds annotations for `#[rustc_regions]`; see `UniversalRegions::annotate`. /// Adds annotations for `#[rustc_regions]`; see `UniversalRegions::annotate`.
pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) { pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut DiagnosticBuilder<'_, ()>) {
self.universal_regions.annotate(tcx, err) self.universal_regions.annotate(tcx, err)
} }

View file

@ -16,7 +16,7 @@
#![allow(rustc::untranslatable_diagnostic)] #![allow(rustc::untranslatable_diagnostic)]
use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::fx::FxIndexMap;
use rustc_errors::Diagnostic; use rustc_errors::DiagnosticBuilder;
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::lang_items::LangItem; use rustc_hir::lang_items::LangItem;
use rustc_hir::BodyOwnerKind; use rustc_hir::BodyOwnerKind;
@ -343,7 +343,7 @@ impl<'tcx> UniversalRegions<'tcx> {
/// that this region imposes on others. The methods in this file /// that this region imposes on others. The methods in this file
/// handle the part about dumping the inference context internal /// handle the part about dumping the inference context internal
/// state. /// state.
pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut Diagnostic) { pub(crate) fn annotate(&self, tcx: TyCtxt<'tcx>, err: &mut DiagnosticBuilder<'_, ()>) {
match self.defining_ty { match self.defining_ty {
DefiningTy::Closure(def_id, args) => { DefiningTy::Closure(def_id, args) => {
let v = with_no_trimmed_paths!( let v = with_no_trimmed_paths!(

View file

@ -1,6 +1,6 @@
use rustc_errors::{ use rustc_errors::{
codes::*, AddToDiagnostic, DiagCtxt, Diagnostic, DiagnosticBuilder, EmissionGuarantee, codes::*, AddToDiagnostic, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic,
IntoDiagnostic, Level, MultiSpan, SingleLabelManySpans, SubdiagnosticMessageOp, Level, MultiSpan, SingleLabelManySpans, SubdiagnosticMessageOp,
}; };
use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_span::{symbol::Ident, Span, Symbol}; use rustc_span::{symbol::Ident, Span, Symbol};
@ -611,7 +611,11 @@ pub(crate) struct FormatUnusedArg {
// Allow the singular form to be a subdiagnostic of the multiple-unused // Allow the singular form to be a subdiagnostic of the multiple-unused
// form of diagnostic. // form of diagnostic.
impl AddToDiagnostic for FormatUnusedArg { impl AddToDiagnostic for FormatUnusedArg {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, f: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
f: F,
) {
diag.arg("named", self.named); diag.arg("named", self.named);
let msg = f(diag, crate::fluent_generated::builtin_macros_format_unused_arg.into()); let msg = f(diag, crate::fluent_generated::builtin_macros_format_unused_arg.into());
diag.span_label(self.span, msg); diag.span_label(self.span, msg);

View file

@ -1856,9 +1856,7 @@ impl SharedEmitterMain {
Ok(SharedEmitterMessage::Diagnostic(diag)) => { Ok(SharedEmitterMessage::Diagnostic(diag)) => {
let dcx = sess.dcx(); let dcx = sess.dcx();
let mut d = rustc_errors::Diagnostic::new_with_messages(diag.lvl, diag.msgs); let mut d = rustc_errors::Diagnostic::new_with_messages(diag.lvl, diag.msgs);
if let Some(code) = diag.code { d.code = diag.code; // may be `None`, that's ok
d.code(code);
}
d.replace_args(diag.args); d.replace_args(diag.args);
dcx.emit_diagnostic(d); dcx.emit_diagnostic(d);
} }

View file

@ -93,6 +93,9 @@ pub struct FnCallNonConst<'tcx> {
} }
impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> { impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
// FIXME: make this translatable
#[allow(rustc::diagnostic_outside_of_impl)]
#[allow(rustc::untranslatable_diagnostic)]
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, _: Span) -> DiagnosticBuilder<'tcx> { fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, _: Span) -> DiagnosticBuilder<'tcx> {
let FnCallNonConst { caller, callee, args, span, call_source, feature } = *self; let FnCallNonConst { caller, callee, args, span, call_source, feature } = *self;
let ConstCx { tcx, param_env, .. } = *ccx; let ConstCx { tcx, param_env, .. } = *ccx;
@ -321,6 +324,8 @@ impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
.dcx() .dcx()
.create_err(errors::UnstableConstFn { span, def_path: ccx.tcx.def_path_str(def_id) }); .create_err(errors::UnstableConstFn { span, def_path: ccx.tcx.def_path_str(def_id) });
// FIXME: make this translatable
#[allow(rustc::untranslatable_diagnostic)]
if ccx.is_const_stable_const_fn() { if ccx.is_const_stable_const_fn() {
err.help("const-stable functions can only call other const-stable functions"); err.help("const-stable functions can only call other const-stable functions");
} else if ccx.tcx.sess.is_nightly_build() { } else if ccx.tcx.sess.is_nightly_build() {
@ -591,6 +596,8 @@ impl<'tcx> NonConstOp<'tcx> for StaticAccess {
span, span,
format!("referencing statics in {}s is unstable", ccx.const_kind(),), format!("referencing statics in {}s is unstable", ccx.const_kind(),),
); );
// FIXME: make this translatable
#[allow(rustc::untranslatable_diagnostic)]
err err
.note("`static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.") .note("`static` and `const` variables can refer to other `const` variables. A `const` variable, however, cannot refer to a `static` variable.")
.help("to fix this, the value can be extracted to a `const` and then used."); .help("to fix this, the value can be extracted to a `const` and then used.");

View file

@ -12,6 +12,7 @@ use rustc_span::{Span, DUMMY_SP};
use std::borrow::Cow; use std::borrow::Cow;
use std::fmt::{self, Debug}; use std::fmt::{self, Debug};
use std::hash::{Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::ops::{Deref, DerefMut};
use std::panic::Location; use std::panic::Location;
/// Error type for `Diagnostic`'s `suggestions` field, indicating that /// Error type for `Diagnostic`'s `suggestions` field, indicating that
@ -71,17 +72,21 @@ where
Self: Sized, Self: Sized,
{ {
/// Add a subdiagnostic to an existing diagnostic. /// Add a subdiagnostic to an existing diagnostic.
fn add_to_diagnostic(self, diag: &mut Diagnostic) { fn add_to_diagnostic<G: EmissionGuarantee>(self, diag: &mut DiagnosticBuilder<'_, G>) {
self.add_to_diagnostic_with(diag, |_, m| m); self.add_to_diagnostic_with(diag, |_, m| m);
} }
/// Add a subdiagnostic to an existing diagnostic where `f` is invoked on every message used /// Add a subdiagnostic to an existing diagnostic where `f` is invoked on every message used
/// (to optionally perform eager translation). /// (to optionally perform eager translation).
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, f: F); fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
f: F,
);
} }
pub trait SubdiagnosticMessageOp = pub trait SubdiagnosticMessageOp<G> =
Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage; Fn(&mut DiagnosticBuilder<'_, G>, SubdiagnosticMessage) -> SubdiagnosticMessage;
/// Trait implemented by lint types. This should not be implemented manually. Instead, use /// Trait implemented by lint types. This should not be implemented manually. Instead, use
/// `#[derive(LintDiagnostic)]` -- see [rustc_macros::LintDiagnostic]. /// `#[derive(LintDiagnostic)]` -- see [rustc_macros::LintDiagnostic].
@ -93,6 +98,10 @@ pub trait DecorateLint<'a, G: EmissionGuarantee> {
fn msg(&self) -> DiagnosticMessage; fn msg(&self) -> DiagnosticMessage;
} }
/// The main part of a diagnostic. Note that `DiagnosticBuilder`, which wraps
/// this type, is used for most operations, and should be used instead whenever
/// possible. This type should only be used when `DiagnosticBuilder`'s lifetime
/// causes difficulties, e.g. when storing diagnostics within `DiagCtxt`.
#[must_use] #[must_use]
#[derive(Clone, Debug, Encodable, Decodable)] #[derive(Clone, Debug, Encodable, Decodable)]
pub struct Diagnostic { pub struct Diagnostic {
@ -289,6 +298,90 @@ impl Diagnostic {
} }
} }
// See comment on `DiagnosticBuilder::subdiagnostic_message_to_diagnostic_message`.
pub(crate) fn subdiagnostic_message_to_diagnostic_message(
&self,
attr: impl Into<SubdiagnosticMessage>,
) -> DiagnosticMessage {
let msg =
self.messages.iter().map(|(msg, _)| msg).next().expect("diagnostic with no messages");
msg.with_subdiagnostic_message(attr.into())
}
pub(crate) fn sub(
&mut self,
level: Level,
message: impl Into<SubdiagnosticMessage>,
span: MultiSpan,
) {
let sub = SubDiagnostic {
level,
messages: vec![(
self.subdiagnostic_message_to_diagnostic_message(message),
Style::NoStyle,
)],
span,
};
self.children.push(sub);
}
pub(crate) fn arg(&mut self, name: impl Into<DiagnosticArgName>, arg: impl IntoDiagnosticArg) {
self.args.insert(name.into(), arg.into_diagnostic_arg());
}
pub fn args(&self) -> impl Iterator<Item = DiagnosticArg<'_>> {
self.args.iter()
}
pub fn replace_args(&mut self, args: FxIndexMap<DiagnosticArgName, DiagnosticArgValue>) {
self.args = args;
}
}
/// `DiagnosticBuilder` impls many `&mut self -> &mut Self` methods. Each one
/// modifies an existing diagnostic, either in a standalone fashion, e.g.
/// `err.code(code);`, or in a chained fashion to make multiple modifications,
/// e.g. `err.code(code).span(span);`.
///
/// This macro creates an equivalent `self -> Self` method, with a `with_`
/// prefix. This can be used in a chained fashion when making a new diagnostic,
/// e.g. `let err = struct_err(msg).with_code(code);`, or emitting a new
/// diagnostic, e.g. `struct_err(msg).with_code(code).emit();`.
///
/// Although the latter method can be used to modify an existing diagnostic,
/// e.g. `err = err.with_code(code);`, this should be avoided because the former
/// method gives shorter code, e.g. `err.code(code);`.
///
/// Note: the `with_` methods are added only when needed. If you want to use
/// one and it's not defined, feel free to add it.
///
/// Note: any doc comments must be within the `with_fn!` call.
macro_rules! with_fn {
{
$with_f:ident,
$(#[$attrs:meta])*
pub fn $f:ident(&mut $self:ident, $($name:ident: $ty:ty),* $(,)?) -> &mut Self {
$($body:tt)*
}
} => {
// The original function.
$(#[$attrs])*
#[doc = concat!("See [`DiagnosticBuilder::", stringify!($f), "()`].")]
pub fn $f(&mut $self, $($name: $ty),*) -> &mut Self {
$($body)*
}
// The `with_*` variant.
$(#[$attrs])*
#[doc = concat!("See [`DiagnosticBuilder::", stringify!($f), "()`].")]
pub fn $with_f(mut $self, $($name: $ty),*) -> Self {
$self.$f($($name),*);
$self
}
};
}
impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
/// Delay emission of this diagnostic as a bug. /// Delay emission of this diagnostic as a bug.
/// ///
/// This can be useful in contexts where an error indicates a bug but /// This can be useful in contexts where an error indicates a bug but
@ -309,6 +402,7 @@ impl Diagnostic {
self.level = Level::DelayedBug; self.level = Level::DelayedBug;
} }
with_fn! { with_span_label,
/// Appends a labeled span to the diagnostic. /// Appends a labeled span to the diagnostic.
/// ///
/// Labels are used to convey additional context for the diagnostic's primary span. They will /// Labels are used to convey additional context for the diagnostic's primary span. They will
@ -323,10 +417,12 @@ impl Diagnostic {
/// primary. /// primary.
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
pub fn span_label(&mut self, span: Span, label: impl Into<SubdiagnosticMessage>) -> &mut Self { pub fn span_label(&mut self, span: Span, label: impl Into<SubdiagnosticMessage>) -> &mut Self {
self.span.push_span_label(span, self.subdiagnostic_message_to_diagnostic_message(label)); let msg = self.subdiagnostic_message_to_diagnostic_message(label);
self.span.push_span_label(span, msg);
self self
} } }
with_fn! { with_span_labels,
/// Labels all the given spans with the provided label. /// Labels all the given spans with the provided label.
/// See [`Self::span_label()`] for more information. /// See [`Self::span_label()`] for more information.
pub fn span_labels(&mut self, spans: impl IntoIterator<Item = Span>, label: &str) -> &mut Self { pub fn span_labels(&mut self, spans: impl IntoIterator<Item = Span>, label: &str) -> &mut Self {
@ -334,7 +430,7 @@ impl Diagnostic {
self.span_label(span, label.to_string()); self.span_label(span, label.to_string());
} }
self self
} } }
pub fn replace_span_with(&mut self, after: Span, keep_label: bool) -> &mut Self { pub fn replace_span_with(&mut self, after: Span, keep_label: bool) -> &mut Self {
let before = self.span.clone(); let before = self.span.clone();
@ -412,39 +508,40 @@ impl Diagnostic {
self self
} }
with_fn! { with_note,
/// Add a note attached to this diagnostic. /// Add a note attached to this diagnostic.
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
pub fn note(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self { pub fn note(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self {
self.sub(Level::Note, msg, MultiSpan::new()); self.sub(Level::Note, msg, MultiSpan::new());
self self
} } }
fn highlighted_note(&mut self, msg: Vec<StringPart>) -> &mut Self { fn highlighted_note(&mut self, msg: Vec<StringPart>) -> &mut Self {
self.sub_with_highlights(Level::Note, msg, MultiSpan::new()); self.sub_with_highlights(Level::Note, msg, MultiSpan::new());
self self
} }
/// Prints the span with a note above it. /// This is like [`DiagnosticBuilder::note()`], but it's only printed once.
/// This is like [`Diagnostic::note()`], but it gets its own span.
pub fn note_once(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self { pub fn note_once(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self {
self.sub(Level::OnceNote, msg, MultiSpan::new()); self.sub(Level::OnceNote, msg, MultiSpan::new());
self self
} }
with_fn! { with_span_note,
/// Prints the span with a note above it. /// Prints the span with a note above it.
/// This is like [`Diagnostic::note()`], but it gets its own span. /// This is like [`DiagnosticBuilder::note()`], but it gets its own span.
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
pub fn span_note<S: Into<MultiSpan>>( pub fn span_note(
&mut self, &mut self,
sp: S, sp: impl Into<MultiSpan>,
msg: impl Into<SubdiagnosticMessage>, msg: impl Into<SubdiagnosticMessage>,
) -> &mut Self { ) -> &mut Self {
self.sub(Level::Note, msg, sp.into()); self.sub(Level::Note, msg, sp.into());
self self
} } }
/// Prints the span with a note above it. /// Prints the span with a note above it.
/// This is like [`Diagnostic::note()`], but it gets its own span. /// This is like [`DiagnosticBuilder::note_once()`], but it gets its own span.
pub fn span_note_once<S: Into<MultiSpan>>( pub fn span_note_once<S: Into<MultiSpan>>(
&mut self, &mut self,
sp: S, sp: S,
@ -454,15 +551,16 @@ impl Diagnostic {
self self
} }
with_fn! { with_warn,
/// Add a warning attached to this diagnostic. /// Add a warning attached to this diagnostic.
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
pub fn warn(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self { pub fn warn(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self {
self.sub(Level::Warning, msg, MultiSpan::new()); self.sub(Level::Warning, msg, MultiSpan::new());
self self
} } }
/// Prints the span with a warning above it. /// Prints the span with a warning above it.
/// This is like [`Diagnostic::warn()`], but it gets its own span. /// This is like [`DiagnosticBuilder::warn()`], but it gets its own span.
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
pub fn span_warn<S: Into<MultiSpan>>( pub fn span_warn<S: Into<MultiSpan>>(
&mut self, &mut self,
@ -473,15 +571,15 @@ impl Diagnostic {
self self
} }
with_fn! { with_help,
/// Add a help message attached to this diagnostic. /// Add a help message attached to this diagnostic.
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
pub fn help(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self { pub fn help(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self {
self.sub(Level::Help, msg, MultiSpan::new()); self.sub(Level::Help, msg, MultiSpan::new());
self self
} } }
/// Prints the span with a help above it. /// This is like [`DiagnosticBuilder::help()`], but it's only printed once.
/// This is like [`Diagnostic::help()`], but it gets its own span.
pub fn help_once(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self { pub fn help_once(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self {
self.sub(Level::OnceHelp, msg, MultiSpan::new()); self.sub(Level::OnceHelp, msg, MultiSpan::new());
self self
@ -494,7 +592,7 @@ impl Diagnostic {
} }
/// Prints the span with some help above it. /// Prints the span with some help above it.
/// This is like [`Diagnostic::help()`], but it gets its own span. /// This is like [`DiagnosticBuilder::help()`], but it gets its own span.
#[rustc_lint_diagnostics] #[rustc_lint_diagnostics]
pub fn span_help<S: Into<MultiSpan>>( pub fn span_help<S: Into<MultiSpan>>(
&mut self, &mut self,
@ -531,6 +629,7 @@ impl Diagnostic {
} }
} }
with_fn! { with_multipart_suggestion,
/// Show a suggestion that has multiple parts to it. /// Show a suggestion that has multiple parts to it.
/// In other words, multiple changes need to be applied as part of this suggestion. /// In other words, multiple changes need to be applied as part of this suggestion.
pub fn multipart_suggestion( pub fn multipart_suggestion(
@ -545,7 +644,7 @@ impl Diagnostic {
applicability, applicability,
SuggestionStyle::ShowCode, SuggestionStyle::ShowCode,
) )
} } }
/// Show a suggestion that has multiple parts to it, always as it's own subdiagnostic. /// Show a suggestion that has multiple parts to it, always as it's own subdiagnostic.
/// In other words, multiple changes need to be applied as part of this suggestion. /// In other words, multiple changes need to be applied as part of this suggestion.
@ -562,7 +661,8 @@ impl Diagnostic {
SuggestionStyle::ShowAlways, SuggestionStyle::ShowAlways,
) )
} }
/// [`Diagnostic::multipart_suggestion()`] but you can set the [`SuggestionStyle`].
/// [`DiagnosticBuilder::multipart_suggestion()`] but you can set the [`SuggestionStyle`].
pub fn multipart_suggestion_with_style( pub fn multipart_suggestion_with_style(
&mut self, &mut self,
msg: impl Into<SubdiagnosticMessage>, msg: impl Into<SubdiagnosticMessage>,
@ -619,6 +719,7 @@ impl Diagnostic {
) )
} }
with_fn! { with_span_suggestion,
/// Prints out a message with a suggested edit of the code. /// Prints out a message with a suggested edit of the code.
/// ///
/// In case of short messages and a simple suggestion, rustc displays it as a label: /// In case of short messages and a simple suggestion, rustc displays it as a label:
@ -651,9 +752,9 @@ impl Diagnostic {
SuggestionStyle::ShowCode, SuggestionStyle::ShowCode,
); );
self self
} } }
/// [`Diagnostic::span_suggestion()`] but you can set the [`SuggestionStyle`]. /// [`DiagnosticBuilder::span_suggestion()`] but you can set the [`SuggestionStyle`].
pub fn span_suggestion_with_style( pub fn span_suggestion_with_style(
&mut self, &mut self,
sp: Span, sp: Span,
@ -677,6 +778,7 @@ impl Diagnostic {
self self
} }
with_fn! { with_span_suggestion_verbose,
/// Always show the suggested change. /// Always show the suggested change.
pub fn span_suggestion_verbose( pub fn span_suggestion_verbose(
&mut self, &mut self,
@ -693,10 +795,11 @@ impl Diagnostic {
SuggestionStyle::ShowAlways, SuggestionStyle::ShowAlways,
); );
self self
} } }
with_fn! { with_span_suggestions,
/// Prints out a message with multiple suggested edits of the code. /// Prints out a message with multiple suggested edits of the code.
/// See also [`Diagnostic::span_suggestion()`]. /// See also [`DiagnosticBuilder::span_suggestion()`].
pub fn span_suggestions( pub fn span_suggestions(
&mut self, &mut self,
sp: Span, sp: Span,
@ -711,9 +814,8 @@ impl Diagnostic {
applicability, applicability,
SuggestionStyle::ShowCode, SuggestionStyle::ShowCode,
) )
} } }
/// [`Diagnostic::span_suggestions()`] but you can set the [`SuggestionStyle`].
pub fn span_suggestions_with_style( pub fn span_suggestions_with_style(
&mut self, &mut self,
sp: Span, sp: Span,
@ -743,7 +845,7 @@ impl Diagnostic {
/// Prints out a message with multiple suggested edits of the code, where each edit consists of /// Prints out a message with multiple suggested edits of the code, where each edit consists of
/// multiple parts. /// multiple parts.
/// See also [`Diagnostic::multipart_suggestion()`]. /// See also [`DiagnosticBuilder::multipart_suggestion()`].
pub fn multipart_suggestions( pub fn multipart_suggestions(
&mut self, &mut self,
msg: impl Into<SubdiagnosticMessage>, msg: impl Into<SubdiagnosticMessage>,
@ -785,6 +887,7 @@ impl Diagnostic {
self self
} }
with_fn! { with_span_suggestion_short,
/// Prints out a message with a suggested edit of the code. If the suggestion is presented /// Prints out a message with a suggested edit of the code. If the suggestion is presented
/// inline, it will only show the message and not the suggestion. /// inline, it will only show the message and not the suggestion.
/// ///
@ -804,7 +907,7 @@ impl Diagnostic {
SuggestionStyle::HideCodeInline, SuggestionStyle::HideCodeInline,
); );
self self
} } }
/// Prints out a message for a suggestion without showing the suggested code. /// Prints out a message for a suggestion without showing the suggested code.
/// ///
@ -829,6 +932,7 @@ impl Diagnostic {
self self
} }
with_fn! { with_tool_only_span_suggestion,
/// Adds a suggestion to the JSON output that will not be shown in the CLI. /// Adds a suggestion to the JSON output that will not be shown in the CLI.
/// ///
/// This is intended to be used for suggestions that are *very* obvious in what the changes /// This is intended to be used for suggestions that are *very* obvious in what the changes
@ -849,7 +953,7 @@ impl Diagnostic {
SuggestionStyle::CompletelyHidden, SuggestionStyle::CompletelyHidden,
); );
self self
} } }
/// Add a subdiagnostic from a type that implements `Subdiagnostic` (see /// Add a subdiagnostic from a type that implements `Subdiagnostic` (see
/// [rustc_macros::Subdiagnostic]). Performs eager translation of any translatable messages /// [rustc_macros::Subdiagnostic]). Performs eager translation of any translatable messages
@ -868,45 +972,45 @@ impl Diagnostic {
self self
} }
pub fn span<S: Into<MultiSpan>>(&mut self, sp: S) -> &mut Self { with_fn! { with_span,
/// Add a span.
pub fn span(&mut self, sp: impl Into<MultiSpan>) -> &mut Self {
self.span = sp.into(); self.span = sp.into();
if let Some(span) = self.span.primary_span() { if let Some(span) = self.span.primary_span() {
self.sort_span = span; self.sort_span = span;
} }
self self
} } }
pub fn is_lint(&mut self, name: String, has_future_breakage: bool) -> &mut Self { pub fn is_lint(&mut self, name: String, has_future_breakage: bool) -> &mut Self {
self.is_lint = Some(IsLint { name, has_future_breakage }); self.is_lint = Some(IsLint { name, has_future_breakage });
self self
} }
with_fn! { with_code,
/// Add an error code.
pub fn code(&mut self, code: ErrCode) -> &mut Self { pub fn code(&mut self, code: ErrCode) -> &mut Self {
self.code = Some(code); self.code = Some(code);
self self
} } }
with_fn! { with_primary_message,
/// Add a primary message.
pub fn primary_message(&mut self, msg: impl Into<DiagnosticMessage>) -> &mut Self { pub fn primary_message(&mut self, msg: impl Into<DiagnosticMessage>) -> &mut Self {
self.messages[0] = (msg.into(), Style::NoStyle); self.messages[0] = (msg.into(), Style::NoStyle);
self self
} } }
pub fn args(&self) -> impl Iterator<Item = DiagnosticArg<'_>> {
self.args.iter()
}
with_fn! { with_arg,
/// Add an argument.
pub fn arg( pub fn arg(
&mut self, &mut self,
name: impl Into<DiagnosticArgName>, name: impl Into<DiagnosticArgName>,
arg: impl IntoDiagnosticArg, arg: impl IntoDiagnosticArg,
) -> &mut Self { ) -> &mut Self {
self.args.insert(name.into(), arg.into_diagnostic_arg()); self.deref_mut().arg(name, arg);
self self
} } }
pub fn replace_args(&mut self, args: FxIndexMap<DiagnosticArgName, DiagnosticArgValue>) {
self.args = args;
}
/// Helper function that takes a `SubdiagnosticMessage` and returns a `DiagnosticMessage` by /// Helper function that takes a `SubdiagnosticMessage` and returns a `DiagnosticMessage` by
/// combining it with the primary message of the diagnostic (if translatable, otherwise it just /// combining it with the primary message of the diagnostic (if translatable, otherwise it just
@ -915,9 +1019,7 @@ impl Diagnostic {
&self, &self,
attr: impl Into<SubdiagnosticMessage>, attr: impl Into<SubdiagnosticMessage>,
) -> DiagnosticMessage { ) -> DiagnosticMessage {
let msg = self.deref().subdiagnostic_message_to_diagnostic_message(attr)
self.messages.iter().map(|(msg, _)| msg).next().expect("diagnostic with no messages");
msg.with_subdiagnostic_message(attr.into())
} }
/// Convenience function for internal use, clients should use one of the /// Convenience function for internal use, clients should use one of the
@ -925,15 +1027,7 @@ impl Diagnostic {
/// ///
/// Used by `proc_macro_server` for implementing `server::Diagnostic`. /// Used by `proc_macro_server` for implementing `server::Diagnostic`.
pub fn sub(&mut self, level: Level, message: impl Into<SubdiagnosticMessage>, span: MultiSpan) { pub fn sub(&mut self, level: Level, message: impl Into<SubdiagnosticMessage>, span: MultiSpan) {
let sub = SubDiagnostic { self.deref_mut().sub(level, message, span);
level,
messages: vec![(
self.subdiagnostic_message_to_diagnostic_message(message),
Style::NoStyle,
)],
span,
};
self.children.push(sub);
} }
/// Convenience function for internal use, clients should use one of the /// Convenience function for internal use, clients should use one of the
@ -946,7 +1040,9 @@ impl Diagnostic {
let sub = SubDiagnostic { level, messages, span }; let sub = SubDiagnostic { level, messages, span };
self.children.push(sub); self.children.push(sub);
} }
}
impl Diagnostic {
/// Fields used for Hash, and PartialEq trait /// Fields used for Hash, and PartialEq trait
fn keys( fn keys(
&self, &self,

View file

@ -1,14 +1,8 @@
use crate::diagnostic::IntoDiagnosticArg;
use crate::{DiagCtxt, Level, MultiSpan, StashKey};
use crate::{ use crate::{
Diagnostic, DiagnosticMessage, DiagnosticStyledString, ErrCode, ErrorGuaranteed, ExplicitBug, DiagCtxt, Diagnostic, DiagnosticMessage, ErrorGuaranteed, ExplicitBug, Level, StashKey,
SubdiagnosticMessage,
}; };
use rustc_lint_defs::Applicability;
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
use rustc_span::Span; use rustc_span::Span;
use std::borrow::Cow;
use std::fmt::{self, Debug}; use std::fmt::{self, Debug};
use std::marker::PhantomData; use std::marker::PhantomData;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
@ -35,6 +29,11 @@ where
} }
/// Used for emitting structured error messages and other diagnostic information. /// Used for emitting structured error messages and other diagnostic information.
/// Wraps a `Diagnostic`, adding some useful things.
/// - The `dcx` field, allowing it to (a) emit itself, and (b) do a drop check
/// that it has been emitted or cancelled.
/// - The `EmissionGuarantee`, which determines the type returned from `emit`.
///
/// Each constructed `DiagnosticBuilder` must be consumed by a function such as /// Each constructed `DiagnosticBuilder` must be consumed by a function such as
/// `emit`, `cancel`, `delay_as_bug`, or `into_diagnostic`. A panic occurrs if a /// `emit`, `cancel`, `delay_as_bug`, or `into_diagnostic`. A panic occurrs if a
/// `DiagnosticBuilder` is dropped without being consumed by one of these /// `DiagnosticBuilder` is dropped without being consumed by one of these
@ -56,9 +55,11 @@ pub struct DiagnosticBuilder<'a, G: EmissionGuarantee = ErrorGuaranteed> {
/// often used as a return value, especially within the frequently-used /// often used as a return value, especially within the frequently-used
/// `PResult` type. In theory, return value optimization (RVO) should avoid /// `PResult` type. In theory, return value optimization (RVO) should avoid
/// unnecessary copying. In practice, it does not (at the time of writing). /// unnecessary copying. In practice, it does not (at the time of writing).
diag: Option<Box<Diagnostic>>, // FIXME(nnethercote) Make private once this moves to diagnostic.rs.
pub(crate) diag: Option<Box<Diagnostic>>,
_marker: PhantomData<G>, // FIXME(nnethercote) Make private once this moves to diagnostic.rs.
pub(crate) _marker: PhantomData<G>,
} }
// Cloning a `DiagnosticBuilder` is a recipe for a diagnostic being emitted // Cloning a `DiagnosticBuilder` is a recipe for a diagnostic being emitted
@ -88,18 +89,21 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
/// Takes the diagnostic. For use by methods that consume the /// Takes the diagnostic. For use by methods that consume the
/// DiagnosticBuilder: `emit`, `cancel`, etc. Afterwards, `drop` is the /// DiagnosticBuilder: `emit`, `cancel`, etc. Afterwards, `drop` is the
/// only code that will be run on `self`. /// only code that will be run on `self`.
fn take_diag(&mut self) -> Diagnostic { // FIXME(nnethercote) Make private once this moves to diagnostic.rs.
pub(crate) fn take_diag(&mut self) -> Diagnostic {
Box::into_inner(self.diag.take().unwrap()) Box::into_inner(self.diag.take().unwrap())
} }
/// Most `emit_producing_guarantee` functions use this as a starting point. /// Most `emit_producing_guarantee` functions use this as a starting point.
fn emit_producing_nothing(mut self) { // FIXME(nnethercote) Make private once this moves to diagnostic.rs.
pub(crate) fn emit_producing_nothing(mut self) {
let diag = self.take_diag(); let diag = self.take_diag();
self.dcx.emit_diagnostic(diag); self.dcx.emit_diagnostic(diag);
} }
/// `ErrorGuaranteed::emit_producing_guarantee` uses this. /// `ErrorGuaranteed::emit_producing_guarantee` uses this.
fn emit_producing_error_guaranteed(mut self) -> ErrorGuaranteed { // FIXME(nnethercote) Make private once this moves to diagnostic.rs.
pub(crate) fn emit_producing_error_guaranteed(mut self) -> ErrorGuaranteed {
let diag = self.take_diag(); let diag = self.take_diag();
// The only error levels that produce `ErrorGuaranteed` are // The only error levels that produce `ErrorGuaranteed` are
@ -168,40 +172,6 @@ impl EmissionGuarantee for rustc_span::fatal_error::FatalError {
} }
} }
/// `DiagnosticBuilder` impls `DerefMut`, which allows access to the fields and
/// methods of the embedded `Diagnostic`. However, that doesn't allow method
/// chaining at the `DiagnosticBuilder` level. Each use of this macro defines
/// two builder methods at that level, both of which wrap the equivalent method
/// in `Diagnostic`.
/// - A `&mut self -> &mut Self` method, with the same name as the underlying
/// `Diagnostic` method. It is mostly to modify existing diagnostics, either
/// in a standalone fashion, e.g. `err.code(code)`, or in a chained fashion
/// to make multiple modifications, e.g. `err.code(code).span(span)`.
/// - A `self -> Self` method, which has a `with_` prefix added.
/// It is mostly used in a chained fashion when producing a new diagnostic,
/// e.g. `let err = struct_err(msg).with_code(code)`, or when emitting a new
/// diagnostic , e.g. `struct_err(msg).with_code(code).emit()`.
///
/// Although the latter method can be used to modify an existing diagnostic,
/// e.g. `err = err.with_code(code)`, this should be avoided because the former
/// method gives shorter code, e.g. `err.code(code)`.
macro_rules! forward {
(
($f:ident, $with_f:ident)($($name:ident: $ty:ty),* $(,)?)
) => {
#[doc = concat!("See [`Diagnostic::", stringify!($f), "()`].")]
pub fn $f(&mut self, $($name: $ty),*) -> &mut Self {
self.diag.as_mut().unwrap().$f($($name),*);
self
}
#[doc = concat!("See [`Diagnostic::", stringify!($f), "()`].")]
pub fn $with_f(mut self, $($name: $ty),*) -> Self {
self.diag.as_mut().unwrap().$f($($name),*);
self
}
};
}
impl<G: EmissionGuarantee> Deref for DiagnosticBuilder<'_, G> { impl<G: EmissionGuarantee> Deref for DiagnosticBuilder<'_, G> {
type Target = Diagnostic; type Target = Diagnostic;
@ -278,135 +248,6 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
self.downgrade_to_delayed_bug(); self.downgrade_to_delayed_bug();
self.emit() self.emit()
} }
forward!((span_label, with_span_label)(
span: Span,
label: impl Into<SubdiagnosticMessage>,
));
forward!((span_labels, with_span_labels)(
spans: impl IntoIterator<Item = Span>,
label: &str,
));
forward!((note_expected_found, with_note_expected_found)(
expected_label: &dyn fmt::Display,
expected: DiagnosticStyledString,
found_label: &dyn fmt::Display,
found: DiagnosticStyledString,
));
forward!((note_expected_found_extra, with_note_expected_found_extra)(
expected_label: &dyn fmt::Display,
expected: DiagnosticStyledString,
found_label: &dyn fmt::Display,
found: DiagnosticStyledString,
expected_extra: &dyn fmt::Display,
found_extra: &dyn fmt::Display,
));
forward!((note, with_note)(
msg: impl Into<SubdiagnosticMessage>,
));
forward!((note_once, with_note_once)(
msg: impl Into<SubdiagnosticMessage>,
));
forward!((span_note, with_span_note)(
sp: impl Into<MultiSpan>,
msg: impl Into<SubdiagnosticMessage>,
));
forward!((span_note_once, with_span_note_once)(
sp: impl Into<MultiSpan>,
msg: impl Into<SubdiagnosticMessage>,
));
forward!((warn, with_warn)(
msg: impl Into<SubdiagnosticMessage>,
));
forward!((span_warn, with_span_warn)(
sp: impl Into<MultiSpan>,
msg: impl Into<SubdiagnosticMessage>,
));
forward!((help, with_help)(
msg: impl Into<SubdiagnosticMessage>,
));
forward!((help_once, with_help_once)(
msg: impl Into<SubdiagnosticMessage>,
));
forward!((span_help, with_span_help_once)(
sp: impl Into<MultiSpan>,
msg: impl Into<SubdiagnosticMessage>,
));
forward!((multipart_suggestion, with_multipart_suggestion)(
msg: impl Into<SubdiagnosticMessage>,
suggestion: Vec<(Span, String)>,
applicability: Applicability,
));
forward!((multipart_suggestion_verbose, with_multipart_suggestion_verbose)(
msg: impl Into<SubdiagnosticMessage>,
suggestion: Vec<(Span, String)>,
applicability: Applicability,
));
forward!((tool_only_multipart_suggestion, with_tool_only_multipart_suggestion)(
msg: impl Into<SubdiagnosticMessage>,
suggestion: Vec<(Span, String)>,
applicability: Applicability,
));
forward!((span_suggestion, with_span_suggestion)(
sp: Span,
msg: impl Into<SubdiagnosticMessage>,
suggestion: impl ToString,
applicability: Applicability,
));
forward!((span_suggestions, with_span_suggestions)(
sp: Span,
msg: impl Into<SubdiagnosticMessage>,
suggestions: impl IntoIterator<Item = String>,
applicability: Applicability,
));
forward!((multipart_suggestions, with_multipart_suggestions)(
msg: impl Into<SubdiagnosticMessage>,
suggestions: impl IntoIterator<Item = Vec<(Span, String)>>,
applicability: Applicability,
));
forward!((span_suggestion_short, with_span_suggestion_short)(
sp: Span,
msg: impl Into<SubdiagnosticMessage>,
suggestion: impl ToString,
applicability: Applicability,
));
forward!((span_suggestion_verbose, with_span_suggestion_verbose)(
sp: Span,
msg: impl Into<SubdiagnosticMessage>,
suggestion: impl ToString,
applicability: Applicability,
));
forward!((span_suggestion_hidden, with_span_suggestion_hidden)(
sp: Span,
msg: impl Into<SubdiagnosticMessage>,
suggestion: impl ToString,
applicability: Applicability,
));
forward!((tool_only_span_suggestion, with_tool_only_span_suggestion)(
sp: Span,
msg: impl Into<SubdiagnosticMessage>,
suggestion: impl ToString,
applicability: Applicability,
));
forward!((primary_message, with_primary_message)(
msg: impl Into<DiagnosticMessage>,
));
forward!((span, with_span)(
sp: impl Into<MultiSpan>,
));
forward!((is_lint, with_is_lint)(
name: String, has_future_breakage: bool,
));
forward!((code, with_code)(
code: ErrCode,
));
forward!((arg, with_arg)(
name: impl Into<Cow<'static, str>>, arg: impl IntoDiagnosticArg,
));
forward!((subdiagnostic, with_subdiagnostic)(
dcx: &DiagCtxt,
subdiagnostic: impl crate::AddToDiagnostic,
));
} }
impl<G: EmissionGuarantee> Debug for DiagnosticBuilder<'_, G> { impl<G: EmissionGuarantee> Debug for DiagnosticBuilder<'_, G> {

View file

@ -299,7 +299,11 @@ pub struct SingleLabelManySpans {
pub label: &'static str, pub label: &'static str,
} }
impl AddToDiagnostic for SingleLabelManySpans { impl AddToDiagnostic for SingleLabelManySpans {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut crate::Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_: F,
) {
diag.span_labels(self.spans, self.label); diag.span_labels(self.spans, self.label);
} }
} }
@ -312,23 +316,6 @@ pub struct ExpectedLifetimeParameter {
pub count: usize, pub count: usize,
} }
#[derive(Subdiagnostic)]
#[note(errors_delayed_at_with_newline)]
pub struct DelayedAtWithNewline {
#[primary_span]
pub span: Span,
pub emitted_at: DiagnosticLocation,
pub note: Backtrace,
}
#[derive(Subdiagnostic)]
#[note(errors_delayed_at_without_newline)]
pub struct DelayedAtWithoutNewline {
#[primary_span]
pub span: Span,
pub emitted_at: DiagnosticLocation,
pub note: Backtrace,
}
impl IntoDiagnosticArg for DiagnosticLocation { impl IntoDiagnosticArg for DiagnosticLocation {
fn into_diagnostic_arg(self) -> DiagnosticArgValue { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::from(self.to_string())) DiagnosticArgValue::Str(Cow::from(self.to_string()))
@ -341,13 +328,6 @@ impl IntoDiagnosticArg for Backtrace {
} }
} }
#[derive(Subdiagnostic)]
#[note(errors_invalid_flushed_delayed_diagnostic_level)]
pub struct InvalidFlushedDelayedDiagnosticLevel {
#[primary_span]
pub span: Span,
pub level: Level,
}
impl IntoDiagnosticArg for Level { impl IntoDiagnosticArg for Level {
fn into_diagnostic_arg(self) -> DiagnosticArgValue { fn into_diagnostic_arg(self) -> DiagnosticArgValue {
DiagnosticArgValue::Str(Cow::from(self.to_string())) DiagnosticArgValue::Str(Cow::from(self.to_string()))

View file

@ -599,7 +599,7 @@ impl Emitter for SilentEmitter {
fn emit_diagnostic(&mut self, mut diag: Diagnostic) { fn emit_diagnostic(&mut self, mut diag: Diagnostic) {
if diag.level == Level::Fatal { if diag.level == Level::Fatal {
diag.note(self.fatal_note.clone()); diag.sub(Level::Note, self.fatal_note.clone(), MultiSpan::new());
self.fatal_dcx.emit_diagnostic(diag); self.fatal_dcx.emit_diagnostic(diag);
} }
} }

View file

@ -46,7 +46,7 @@ pub use diagnostic_builder::{
}; };
pub use diagnostic_impls::{ pub use diagnostic_impls::{
DiagnosticArgFromDisplay, DiagnosticSymbolList, ExpectedLifetimeParameter, DiagnosticArgFromDisplay, DiagnosticSymbolList, ExpectedLifetimeParameter,
IndicateAnonymousLifetime, InvalidFlushedDelayedDiagnosticLevel, SingleLabelManySpans, IndicateAnonymousLifetime, SingleLabelManySpans,
}; };
pub use emitter::ColorConfig; pub use emitter::ColorConfig;
pub use rustc_error_messages::{ pub use rustc_error_messages::{
@ -62,7 +62,6 @@ pub use snippet::Style;
// See https://github.com/rust-lang/rust/pull/115393. // See https://github.com/rust-lang/rust/pull/115393.
pub use termcolor::{Color, ColorSpec, WriteColor}; pub use termcolor::{Color, ColorSpec, WriteColor};
use crate::diagnostic_impls::{DelayedAtWithNewline, DelayedAtWithoutNewline};
use emitter::{is_case_difference, DynEmitter, Emitter, HumanEmitter}; use emitter::{is_case_difference, DynEmitter, Emitter, HumanEmitter};
use registry::Registry; use registry::Registry;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
@ -1395,9 +1394,8 @@ impl DiagCtxtInner {
}; };
diagnostic.children.extract_if(already_emitted_sub).for_each(|_| {}); diagnostic.children.extract_if(already_emitted_sub).for_each(|_| {});
if already_emitted { if already_emitted {
diagnostic.note( let msg = "duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`";
"duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`", diagnostic.sub(Level::Note, msg, MultiSpan::new());
);
} }
if is_error { if is_error {
@ -1483,6 +1481,16 @@ impl DiagCtxtInner {
self.emitter.translate_message(&message, &args).map_err(Report::new).unwrap().to_string() self.emitter.translate_message(&message, &args).map_err(Report::new).unwrap().to_string()
} }
fn eagerly_translate_for_subdiag(
&self,
diag: &Diagnostic,
msg: impl Into<SubdiagnosticMessage>,
) -> SubdiagnosticMessage {
let args = diag.args();
let msg = diag.subdiagnostic_message_to_diagnostic_message(msg);
self.eagerly_translate(msg, args)
}
fn flush_delayed(&mut self) { fn flush_delayed(&mut self) {
if self.delayed_bugs.is_empty() { if self.delayed_bugs.is_empty() {
return; return;
@ -1527,17 +1535,14 @@ impl DiagCtxtInner {
if bug.level != DelayedBug { if bug.level != DelayedBug {
// NOTE(eddyb) not panicking here because we're already producing // NOTE(eddyb) not panicking here because we're already producing
// an ICE, and the more information the merrier. // an ICE, and the more information the merrier.
let subdiag = InvalidFlushedDelayedDiagnosticLevel { //
span: bug.span.primary_span().unwrap(), // We are at the `Diagnostic`/`DiagCtxtInner` level rather than
level: bug.level, // the usual `DiagnosticBuilder`/`DiagCtxt` level, so we must
}; // augment `bug` in a lower-level fashion.
// FIXME: Cannot use `Diagnostic::subdiagnostic` which takes `DiagCtxt`, but it bug.arg("level", bug.level);
// just uses `DiagCtxtInner` functions. let msg = crate::fluent_generated::errors_invalid_flushed_delayed_diagnostic_level;
subdiag.add_to_diagnostic_with(&mut bug, |diag, msg| { let msg = self.eagerly_translate_for_subdiag(&bug, msg); // after the `arg` call
let args = diag.args(); bug.sub(Level::Note, msg, bug.span.primary_span().unwrap().into());
let msg = diag.subdiagnostic_message_to_diagnostic_message(msg);
self.eagerly_translate(msg, args)
});
} }
bug.level = Bug; bug.level = Bug;
@ -1571,39 +1576,22 @@ impl DelayedDiagnostic {
DelayedDiagnostic { inner: diagnostic, note: backtrace } DelayedDiagnostic { inner: diagnostic, note: backtrace }
} }
fn decorate(mut self, dcx: &DiagCtxtInner) -> Diagnostic { fn decorate(self, dcx: &DiagCtxtInner) -> Diagnostic {
// FIXME: Cannot use `Diagnostic::subdiagnostic` which takes `DiagCtxt`, but it // We are at the `Diagnostic`/`DiagCtxtInner` level rather than the
// just uses `DiagCtxtInner` functions. // usual `DiagnosticBuilder`/`DiagCtxt` level, so we must construct
let subdiag_with = |diag: &mut Diagnostic, msg| { // `diag` in a lower-level fashion.
let args = diag.args(); let mut diag = self.inner;
let msg = diag.subdiagnostic_message_to_diagnostic_message(msg); let msg = match self.note.status() {
dcx.eagerly_translate(msg, args) BacktraceStatus::Captured => crate::fluent_generated::errors_delayed_at_with_newline,
};
match self.note.status() {
BacktraceStatus::Captured => {
let inner = &self.inner;
let subdiag = DelayedAtWithNewline {
span: inner.span.primary_span().unwrap_or(DUMMY_SP),
emitted_at: inner.emitted_at.clone(),
note: self.note,
};
subdiag.add_to_diagnostic_with(&mut self.inner, subdiag_with);
}
// Avoid the needless newline when no backtrace has been captured, // Avoid the needless newline when no backtrace has been captured,
// the display impl should just be a single line. // the display impl should just be a single line.
_ => { _ => crate::fluent_generated::errors_delayed_at_without_newline,
let inner = &self.inner;
let subdiag = DelayedAtWithoutNewline {
span: inner.span.primary_span().unwrap_or(DUMMY_SP),
emitted_at: inner.emitted_at.clone(),
note: self.note,
}; };
subdiag.add_to_diagnostic_with(&mut self.inner, subdiag_with); diag.arg("emitted_at", diag.emitted_at.clone());
} diag.arg("note", self.note);
} let msg = dcx.eagerly_translate_for_subdiag(&diag, msg); // after the `arg` calls
diag.sub(Level::Note, msg, diag.span.primary_span().unwrap_or(DUMMY_SP).into());
self.inner diag
} }
} }
@ -1745,9 +1733,9 @@ impl Level {
} }
// FIXME(eddyb) this doesn't belong here AFAICT, should be moved to callsite. // FIXME(eddyb) this doesn't belong here AFAICT, should be moved to callsite.
pub fn add_elided_lifetime_in_path_suggestion<E: EmissionGuarantee>( pub fn add_elided_lifetime_in_path_suggestion<G: EmissionGuarantee>(
source_map: &SourceMap, source_map: &SourceMap,
diag: &mut DiagnosticBuilder<'_, E>, diag: &mut DiagnosticBuilder<'_, G>,
n: usize, n: usize,
path_span: Span, path_span: Span,
incl_angl_brckt: bool, incl_angl_brckt: bool,

View file

@ -1176,6 +1176,8 @@ impl<'a> ExtCtxt<'a> {
for (span, notes) in self.expansions.iter() { for (span, notes) in self.expansions.iter() {
let mut db = self.dcx().create_note(errors::TraceMacro { span: *span }); let mut db = self.dcx().create_note(errors::TraceMacro { span: *span });
for note in notes { for note in notes {
// FIXME: make this translatable
#[allow(rustc::untranslatable_diagnostic)]
db.note(note.clone()); db.note(note.clone());
} }
db.emit(); db.emit();

View file

@ -384,6 +384,7 @@ impl<'a> StripUnconfigured<'a> {
); );
if attr.is_doc_comment() { if attr.is_doc_comment() {
#[allow(rustc::untranslatable_diagnostic)]
err.help("`///` is for documentation comments. For a plain comment, use `//`."); err.help("`///` is for documentation comments. For a plain comment, use `//`.");
} }

View file

@ -7,7 +7,7 @@ use crate::mbe::{
use rustc_ast::token::{self, Token, TokenKind}; use rustc_ast::token::{self, Token, TokenKind};
use rustc_ast::tokenstream::TokenStream; use rustc_ast::tokenstream::TokenStream;
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
use rustc_errors::{Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, DiagnosticMessage}; use rustc_errors::{Applicability, DiagCtxt, DiagnosticBuilder, DiagnosticMessage};
use rustc_parse::parser::{Parser, Recovery}; use rustc_parse::parser::{Parser, Recovery};
use rustc_span::source_map::SourceMap; use rustc_span::source_map::SourceMap;
use rustc_span::symbol::Ident; use rustc_span::symbol::Ident;
@ -285,7 +285,11 @@ pub(super) fn emit_frag_parse_err(
e.emit(); e.emit();
} }
pub(crate) fn annotate_err_with_kind(err: &mut Diagnostic, kind: AstFragmentKind, span: Span) { pub(crate) fn annotate_err_with_kind(
err: &mut DiagnosticBuilder<'_>,
kind: AstFragmentKind,
span: Span,
) {
match kind { match kind {
AstFragmentKind::Ty => { AstFragmentKind::Ty => {
err.span_label(span, "this macro call doesn't expand to a type"); err.span_label(span, "this macro call doesn't expand to a type");
@ -313,7 +317,7 @@ enum ExplainDocComment {
pub(super) fn annotate_doc_comment( pub(super) fn annotate_doc_comment(
dcx: &DiagCtxt, dcx: &DiagCtxt,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
sm: &SourceMap, sm: &SourceMap,
span: Span, span: Span,
) { ) {

View file

@ -10,7 +10,7 @@ use rustc_ast::util::literal::escape_byte_str_symbol;
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
use rustc_errors::{ErrorGuaranteed, MultiSpan, PResult}; use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, MultiSpan, PResult};
use rustc_parse::lexer::nfc_normalize; use rustc_parse::lexer::nfc_normalize;
use rustc_parse::parse_stream_from_source_str; use rustc_parse::parse_stream_from_source_str;
use rustc_session::parse::ParseSess; use rustc_session::parse::ParseSess;
@ -509,13 +509,14 @@ impl server::FreeFunctions for Rustc<'_, '_> {
} }
fn emit_diagnostic(&mut self, diagnostic: Diagnostic<Self::Span>) { fn emit_diagnostic(&mut self, diagnostic: Diagnostic<Self::Span>) {
let mut diag = let message = rustc_errors::DiagnosticMessage::from(diagnostic.message);
rustc_errors::Diagnostic::new(diagnostic.level.to_internal(), diagnostic.message); let mut diag: DiagnosticBuilder<'_, rustc_errors::ErrorGuaranteed> =
DiagnosticBuilder::new(&self.sess().dcx, diagnostic.level.to_internal(), message);
diag.span(MultiSpan::from_spans(diagnostic.spans)); diag.span(MultiSpan::from_spans(diagnostic.spans));
for child in diagnostic.children { for child in diagnostic.children {
diag.sub(child.level.to_internal(), child.message, MultiSpan::from_spans(child.spans)); diag.sub(child.level.to_internal(), child.message, MultiSpan::from_spans(child.spans));
} }
self.sess().dcx.emit_diagnostic(diag); diag.emit();
} }
} }

View file

@ -9,7 +9,7 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::sorted_map::SortedMap;
use rustc_data_structures::unord::UnordMap; use rustc_data_structures::unord::UnordMap;
use rustc_errors::{ use rustc_errors::{
codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, ErrorGuaranteed, codes::*, pluralize, struct_span_code_err, Applicability, DiagnosticBuilder, ErrorGuaranteed,
}; };
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
@ -371,7 +371,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
// FIXME(fmease): Heavily adapted from `rustc_hir_typeck::method::suggest`. Deduplicate. // FIXME(fmease): Heavily adapted from `rustc_hir_typeck::method::suggest`. Deduplicate.
fn note_ambiguous_inherent_assoc_type( fn note_ambiguous_inherent_assoc_type(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
candidates: Vec<DefId>, candidates: Vec<DefId>,
span: Span, span: Span,
) { ) {
@ -429,7 +429,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
let tcx = self.tcx(); let tcx = self.tcx();
let adt_did = self_ty.ty_adt_def().map(|def| def.did()); let adt_did = self_ty.ty_adt_def().map(|def| def.did());
let add_def_label = |err: &mut Diagnostic| { let add_def_label = |err: &mut DiagnosticBuilder<'_>| {
if let Some(did) = adt_did { if let Some(did) = adt_did {
err.span_label( err.span_label(
tcx.def_span(did), tcx.def_span(did),

View file

@ -6,7 +6,7 @@ use crate::astconv::{
use crate::structured_errors::{GenericArgsInfo, StructuredDiagnostic, WrongNumberOfGenericArgs}; use crate::structured_errors::{GenericArgsInfo, StructuredDiagnostic, WrongNumberOfGenericArgs};
use rustc_ast::ast::ParamKindOrd; use rustc_ast::ast::ParamKindOrd;
use rustc_errors::{ use rustc_errors::{
codes::*, struct_span_code_err, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan, codes::*, struct_span_code_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan,
}; };
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
@ -47,7 +47,7 @@ fn generic_arg_mismatch_err(
} }
} }
let add_braces_suggestion = |arg: &GenericArg<'_>, err: &mut Diagnostic| { let add_braces_suggestion = |arg: &GenericArg<'_>, err: &mut DiagnosticBuilder<'_>| {
let suggestions = vec![ let suggestions = vec![
(arg.span().shrink_to_lo(), String::from("{ ")), (arg.span().shrink_to_lo(), String::from("{ ")),
(arg.span().shrink_to_hi(), String::from(" }")), (arg.span().shrink_to_hi(), String::from(" }")),

View file

@ -1,5 +1,5 @@
use rustc_ast::TraitObjectSyntax; use rustc_ast::TraitObjectSyntax;
use rustc_errors::{codes::*, Diagnostic, StashKey}; use rustc_errors::{codes::*, DiagnosticBuilder, EmissionGuarantee, StashKey};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{DefKind, Res}; use rustc_hir::def::{DefKind, Res};
use rustc_lint_defs::{builtin::BARE_TRAIT_OBJECTS, Applicability}; use rustc_lint_defs::{builtin::BARE_TRAIT_OBJECTS, Applicability};
@ -10,10 +10,10 @@ use super::AstConv;
impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
/// Make sure that we are in the condition to suggest the blanket implementation. /// Make sure that we are in the condition to suggest the blanket implementation.
pub(super) fn maybe_lint_blanket_trait_impl( pub(super) fn maybe_lint_blanket_trait_impl<G: EmissionGuarantee>(
&self, &self,
self_ty: &hir::Ty<'_>, self_ty: &hir::Ty<'_>,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_, G>,
) { ) {
let tcx = self.tcx(); let tcx = self.tcx();
let parent_id = tcx.hir().get_parent_item(self_ty.hir_id).def_id; let parent_id = tcx.hir().get_parent_item(self_ty.hir_id).def_id;
@ -75,7 +75,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
} }
/// Make sure that we are in the condition to suggest `impl Trait`. /// Make sure that we are in the condition to suggest `impl Trait`.
fn maybe_lint_impl_trait(&self, self_ty: &hir::Ty<'_>, diag: &mut Diagnostic) -> bool { fn maybe_lint_impl_trait(
&self,
self_ty: &hir::Ty<'_>,
diag: &mut DiagnosticBuilder<'_>,
) -> bool {
let tcx = self.tcx(); let tcx = self.tcx();
let parent_id = tcx.hir().get_parent_item(self_ty.hir_id).def_id; let parent_id = tcx.hir().get_parent_item(self_ty.hir_id).def_id;
let (sig, generics, owner) = match tcx.hir_node_by_def_id(parent_id) { let (sig, generics, owner) = match tcx.hir_node_by_def_id(parent_id) {

View file

@ -18,8 +18,8 @@ use crate::require_c_abi_if_c_variadic;
use rustc_ast::TraitObjectSyntax; use rustc_ast::TraitObjectSyntax;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_errors::{ use rustc_errors::{
codes::*, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, codes::*, struct_span_code_err, Applicability, DiagnosticBuilder, ErrorGuaranteed, FatalError,
FatalError, MultiSpan, MultiSpan,
}; };
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Namespace, Res}; use rustc_hir::def::{CtorOf, DefKind, Namespace, Res};
@ -1724,7 +1724,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
pub fn prohibit_generics<'a>( pub fn prohibit_generics<'a>(
&self, &self,
segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone, segments: impl Iterator<Item = &'a hir::PathSegment<'a>> + Clone,
extend: impl Fn(&mut Diagnostic), extend: impl Fn(&mut DiagnosticBuilder<'_>),
) -> bool { ) -> bool {
let args = segments.clone().flat_map(|segment| segment.args().args); let args = segments.clone().flat_map(|segment| segment.args().args);

View file

@ -1248,7 +1248,7 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) {
fn detect_discriminant_duplicate<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>) { fn detect_discriminant_duplicate<'tcx>(tcx: TyCtxt<'tcx>, adt: ty::AdtDef<'tcx>) {
// Helper closure to reduce duplicate code. This gets called everytime we detect a duplicate. // Helper closure to reduce duplicate code. This gets called everytime we detect a duplicate.
// Here `idx` refers to the order of which the discriminant appears, and its index in `vs` // Here `idx` refers to the order of which the discriminant appears, and its index in `vs`
let report = |dis: Discr<'tcx>, idx, err: &mut Diagnostic| { let report = |dis: Discr<'tcx>, idx, err: &mut DiagnosticBuilder<'_>| {
let var = adt.variant(idx); // HIR for the duplicate discriminant let var = adt.variant(idx); // HIR for the duplicate discriminant
let (span, display_discr) = match var.discr { let (span, display_discr) = match var.discr {
ty::VariantDiscr::Explicit(discr_def_id) => { ty::VariantDiscr::Explicit(discr_def_id) => {

View file

@ -78,7 +78,7 @@ use std::num::NonZero;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
use rustc_errors::ErrorGuaranteed; use rustc_errors::ErrorGuaranteed;
use rustc_errors::{pluralize, struct_span_code_err, Diagnostic, DiagnosticBuilder}; use rustc_errors::{pluralize, struct_span_code_err, DiagnosticBuilder};
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
use rustc_index::bit_set::BitSet; use rustc_index::bit_set::BitSet;

View file

@ -1,5 +1,5 @@
use crate::structured_errors::StructuredDiagnostic; use crate::structured_errors::StructuredDiagnostic;
use rustc_errors::{codes::*, pluralize, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan}; use rustc_errors::{codes::*, pluralize, Applicability, DiagnosticBuilder, MultiSpan};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_middle::ty::{self as ty, AssocItems, AssocKind, TyCtxt}; use rustc_middle::ty::{self as ty, AssocItems, AssocKind, TyCtxt};
use rustc_session::Session; use rustc_session::Session;
@ -525,7 +525,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
} }
/// Builds the `expected 1 type argument / supplied 2 type arguments` message. /// Builds the `expected 1 type argument / supplied 2 type arguments` message.
fn notify(&self, err: &mut Diagnostic) { fn notify(&self, err: &mut DiagnosticBuilder<'_>) {
let (quantifier, bound) = self.get_quantifier_and_bound(); let (quantifier, bound) = self.get_quantifier_and_bound();
let provided_args = self.num_provided_args(); let provided_args = self.num_provided_args();
@ -577,7 +577,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
} }
} }
fn suggest(&self, err: &mut Diagnostic) { fn suggest(&self, err: &mut DiagnosticBuilder<'_>) {
debug!( debug!(
"suggest(self.provided {:?}, self.gen_args.span(): {:?})", "suggest(self.provided {:?}, self.gen_args.span(): {:?})",
self.num_provided_args(), self.num_provided_args(),
@ -605,7 +605,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
/// ```text /// ```text
/// type Map = HashMap<String>; /// type Map = HashMap<String>;
/// ``` /// ```
fn suggest_adding_args(&self, err: &mut Diagnostic) { fn suggest_adding_args(&self, err: &mut DiagnosticBuilder<'_>) {
if self.gen_args.parenthesized != hir::GenericArgsParentheses::No { if self.gen_args.parenthesized != hir::GenericArgsParentheses::No {
return; return;
} }
@ -624,7 +624,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
} }
} }
fn suggest_adding_lifetime_args(&self, err: &mut Diagnostic) { fn suggest_adding_lifetime_args(&self, err: &mut DiagnosticBuilder<'_>) {
debug!("suggest_adding_lifetime_args(path_segment: {:?})", self.path_segment); debug!("suggest_adding_lifetime_args(path_segment: {:?})", self.path_segment);
let num_missing_args = self.num_missing_lifetime_args(); let num_missing_args = self.num_missing_lifetime_args();
let num_params_to_take = num_missing_args; let num_params_to_take = num_missing_args;
@ -678,7 +678,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
} }
} }
fn suggest_adding_type_and_const_args(&self, err: &mut Diagnostic) { fn suggest_adding_type_and_const_args(&self, err: &mut DiagnosticBuilder<'_>) {
let num_missing_args = self.num_missing_type_or_const_args(); let num_missing_args = self.num_missing_type_or_const_args();
let msg = format!("add missing {} argument{}", self.kind(), pluralize!(num_missing_args)); let msg = format!("add missing {} argument{}", self.kind(), pluralize!(num_missing_args));
@ -738,7 +738,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
/// ```compile_fail /// ```compile_fail
/// Into::into::<Option<_>>(42) // suggests considering `Into::<Option<_>>::into(42)` /// Into::into::<Option<_>>(42) // suggests considering `Into::<Option<_>>::into(42)`
/// ``` /// ```
fn suggest_moving_args_from_assoc_fn_to_trait(&self, err: &mut Diagnostic) { fn suggest_moving_args_from_assoc_fn_to_trait(&self, err: &mut DiagnosticBuilder<'_>) {
let trait_ = match self.tcx.trait_of_item(self.def_id) { let trait_ = match self.tcx.trait_of_item(self.def_id) {
Some(def_id) => def_id, Some(def_id) => def_id,
None => return, None => return,
@ -794,7 +794,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
fn suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path( fn suggest_moving_args_from_assoc_fn_to_trait_for_qualified_path(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
qpath: &'tcx hir::QPath<'tcx>, qpath: &'tcx hir::QPath<'tcx>,
msg: String, msg: String,
num_assoc_fn_excess_args: usize, num_assoc_fn_excess_args: usize,
@ -827,7 +827,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
fn suggest_moving_args_from_assoc_fn_to_trait_for_method_call( fn suggest_moving_args_from_assoc_fn_to_trait_for_method_call(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
trait_def_id: DefId, trait_def_id: DefId,
expr: &'tcx hir::Expr<'tcx>, expr: &'tcx hir::Expr<'tcx>,
msg: String, msg: String,
@ -881,7 +881,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
/// ```text /// ```text
/// type Map = HashMap<String, String, String, String>; /// type Map = HashMap<String, String, String, String>;
/// ``` /// ```
fn suggest_removing_args_or_generics(&self, err: &mut Diagnostic) { fn suggest_removing_args_or_generics(&self, err: &mut DiagnosticBuilder<'_>) {
let num_provided_lt_args = self.num_provided_lifetime_args(); let num_provided_lt_args = self.num_provided_lifetime_args();
let num_provided_type_const_args = self.num_provided_type_or_const_args(); let num_provided_type_const_args = self.num_provided_type_or_const_args();
let unbound_types = self.get_unbound_associated_types(); let unbound_types = self.get_unbound_associated_types();
@ -899,7 +899,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
let provided_args_matches_unbound_traits = let provided_args_matches_unbound_traits =
unbound_types.len() == num_redundant_type_or_const_args; unbound_types.len() == num_redundant_type_or_const_args;
let remove_lifetime_args = |err: &mut Diagnostic| { let remove_lifetime_args = |err: &mut DiagnosticBuilder<'_>| {
let mut lt_arg_spans = Vec::new(); let mut lt_arg_spans = Vec::new();
let mut found_redundant = false; let mut found_redundant = false;
for arg in self.gen_args.args { for arg in self.gen_args.args {
@ -940,7 +940,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
); );
}; };
let remove_type_or_const_args = |err: &mut Diagnostic| { let remove_type_or_const_args = |err: &mut DiagnosticBuilder<'_>| {
let mut gen_arg_spans = Vec::new(); let mut gen_arg_spans = Vec::new();
let mut found_redundant = false; let mut found_redundant = false;
for arg in self.gen_args.args { for arg in self.gen_args.args {
@ -1037,7 +1037,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
} }
/// Builds the `type defined here` message. /// Builds the `type defined here` message.
fn show_definition(&self, err: &mut Diagnostic) { fn show_definition(&self, err: &mut DiagnosticBuilder<'_>) {
let mut spans: MultiSpan = if let Some(def_span) = self.tcx.def_ident_span(self.def_id) { let mut spans: MultiSpan = if let Some(def_span) = self.tcx.def_ident_span(self.def_id) {
if self.tcx.sess.source_map().is_span_accessible(def_span) { if self.tcx.sess.source_map().is_span_accessible(def_span) {
def_span.into() def_span.into()
@ -1088,7 +1088,7 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
} }
/// Add note if `impl Trait` is explicitly specified. /// Add note if `impl Trait` is explicitly specified.
fn note_synth_provided(&self, err: &mut Diagnostic) { fn note_synth_provided(&self, err: &mut DiagnosticBuilder<'_>) {
if !self.is_synth_provided() { if !self.is_synth_provided() {
return; return;
} }

View file

@ -1,6 +1,6 @@
use crate::coercion::{AsCoercionSite, CoerceMany}; use crate::coercion::{AsCoercionSite, CoerceMany};
use crate::{Diverges, Expectation, FnCtxt, Needs}; use crate::{Diverges, Expectation, FnCtxt, Needs};
use rustc_errors::{Applicability, Diagnostic}; use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir::{ use rustc_hir::{
self as hir, self as hir,
def::{CtorOf, DefKind, Res}, def::{CtorOf, DefKind, Res},
@ -177,7 +177,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn explain_never_type_coerced_to_unit( fn explain_never_type_coerced_to_unit(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
arm: &hir::Arm<'tcx>, arm: &hir::Arm<'tcx>,
arm_ty: Ty<'tcx>, arm_ty: Ty<'tcx>,
prior_arm: Option<(Option<hir::HirId>, Ty<'tcx>, Span)>, prior_arm: Option<(Option<hir::HirId>, Ty<'tcx>, Span)>,
@ -209,7 +209,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn suggest_removing_semicolon_for_coerce( fn suggest_removing_semicolon_for_coerce(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'tcx>, expr: &hir::Expr<'tcx>,
arm_ty: Ty<'tcx>, arm_ty: Ty<'tcx>,
prior_arm: Option<(Option<hir::HirId>, Ty<'tcx>, Span)>, prior_arm: Option<(Option<hir::HirId>, Ty<'tcx>, Span)>,
@ -303,7 +303,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// `if let PAT = EXPR {}` expressions that could be turned into `let PAT = EXPR;`. /// `if let PAT = EXPR {}` expressions that could be turned into `let PAT = EXPR;`.
fn explain_if_expr( fn explain_if_expr(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
ret_reason: Option<(Span, String)>, ret_reason: Option<(Span, String)>,
if_span: Span, if_span: Span,
cond_expr: &'tcx hir::Expr<'tcx>, cond_expr: &'tcx hir::Expr<'tcx>,

View file

@ -4,7 +4,7 @@ use super::{Expectation, FnCtxt, TupleArgumentsFlag};
use crate::errors; use crate::errors;
use rustc_ast::util::parser::PREC_POSTFIX; use rustc_ast::util::parser::PREC_POSTFIX;
use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, StashKey}; use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, StashKey};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{self, CtorKind, Namespace, Res}; use rustc_hir::def::{self, CtorKind, Namespace, Res};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
@ -347,7 +347,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// likely intention is to call the closure, suggest `(||{})()`. (#55851) /// likely intention is to call the closure, suggest `(||{})()`. (#55851)
fn identify_bad_closure_def_and_call( fn identify_bad_closure_def_and_call(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
hir_id: hir::HirId, hir_id: hir::HirId,
callee_node: &hir::ExprKind<'_>, callee_node: &hir::ExprKind<'_>,
callee_span: Span, callee_span: Span,
@ -410,7 +410,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// likely intention is to create an array containing tuples. /// likely intention is to create an array containing tuples.
fn maybe_suggest_bad_array_definition( fn maybe_suggest_bad_array_definition(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
call_expr: &'tcx hir::Expr<'tcx>, call_expr: &'tcx hir::Expr<'tcx>,
callee_expr: &'tcx hir::Expr<'tcx>, callee_expr: &'tcx hir::Expr<'tcx>,
) -> bool { ) -> bool {
@ -601,7 +601,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// and suggesting the fix if the method probe is successful. /// and suggesting the fix if the method probe is successful.
fn suggest_call_as_method( fn suggest_call_as_method(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_, ()>,
segment: &'tcx hir::PathSegment<'tcx>, segment: &'tcx hir::PathSegment<'tcx>,
arg_exprs: &'tcx [hir::Expr<'tcx>], arg_exprs: &'tcx [hir::Expr<'tcx>],
call_expr: &'tcx hir::Expr<'tcx>, call_expr: &'tcx hir::Expr<'tcx>,

View file

@ -33,7 +33,7 @@ use super::FnCtxt;
use crate::errors; use crate::errors;
use crate::type_error_struct; use crate::type_error_struct;
use hir::ExprKind; use hir::ExprKind;
use rustc_errors::{codes::*, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed}; use rustc_errors::{codes::*, Applicability, DiagnosticBuilder, ErrorGuaranteed};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_macros::{TypeFoldable, TypeVisitable}; use rustc_macros::{TypeFoldable, TypeVisitable};
use rustc_middle::mir::Mutability; use rustc_middle::mir::Mutability;
@ -983,7 +983,11 @@ impl<'a, 'tcx> CastCheck<'tcx> {
/// Attempt to suggest using `.is_empty` when trying to cast from a /// Attempt to suggest using `.is_empty` when trying to cast from a
/// collection type to a boolean. /// collection type to a boolean.
fn try_suggest_collection_to_bool(&self, fcx: &FnCtxt<'a, 'tcx>, err: &mut Diagnostic) { fn try_suggest_collection_to_bool(
&self,
fcx: &FnCtxt<'a, 'tcx>,
err: &mut DiagnosticBuilder<'_>,
) {
if self.cast_ty.is_bool() { if self.cast_ty.is_bool() {
let derefed = fcx let derefed = fcx
.autoderef(self.expr_span, self.expr_ty) .autoderef(self.expr_span, self.expr_ty)

View file

@ -36,9 +36,7 @@
//! ``` //! ```
use crate::FnCtxt; use crate::FnCtxt;
use rustc_errors::{ use rustc_errors::{codes::*, struct_span_code_err, Applicability, DiagnosticBuilder, MultiSpan};
codes::*, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, MultiSpan,
};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::intravisit::{self, Visitor};
@ -1439,7 +1437,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
&mut self, &mut self,
fcx: &FnCtxt<'a, 'tcx>, fcx: &FnCtxt<'a, 'tcx>,
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
augment_error: impl FnOnce(&mut Diagnostic), augment_error: impl FnOnce(&mut DiagnosticBuilder<'_>),
label_unit_as_expected: bool, label_unit_as_expected: bool,
) { ) {
self.coerce_inner( self.coerce_inner(
@ -1462,7 +1460,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
expression: Option<&'tcx hir::Expr<'tcx>>, expression: Option<&'tcx hir::Expr<'tcx>>,
mut expression_ty: Ty<'tcx>, mut expression_ty: Ty<'tcx>,
augment_error: impl FnOnce(&mut Diagnostic), augment_error: impl FnOnce(&mut DiagnosticBuilder<'_>),
label_expression_as_expected: bool, label_expression_as_expected: bool,
) { ) {
// Incorporate whatever type inference information we have // Incorporate whatever type inference information we have
@ -1673,7 +1671,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
fn note_unreachable_loop_return( fn note_unreachable_loop_return(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
expr: &hir::Expr<'tcx>, expr: &hir::Expr<'tcx>,
ret_exprs: &Vec<&'tcx hir::Expr<'tcx>>, ret_exprs: &Vec<&'tcx hir::Expr<'tcx>>,

View file

@ -1,6 +1,6 @@
use crate::FnCtxt; use crate::FnCtxt;
use rustc_errors::MultiSpan; use rustc_errors::MultiSpan;
use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder}; use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::Res; use rustc_hir::def::Res;
use rustc_hir::intravisit::Visitor; use rustc_hir::intravisit::Visitor;
@ -19,7 +19,7 @@ use super::method::probe;
impl<'a, 'tcx> FnCtxt<'a, 'tcx> { impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub fn emit_type_mismatch_suggestions( pub fn emit_type_mismatch_suggestions(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'tcx>, expr: &hir::Expr<'tcx>,
expr_ty: Ty<'tcx>, expr_ty: Ty<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
@ -70,7 +70,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub fn emit_coerce_suggestions( pub fn emit_coerce_suggestions(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'tcx>, expr: &hir::Expr<'tcx>,
expr_ty: Ty<'tcx>, expr_ty: Ty<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
@ -280,7 +280,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// with some expectation given by `source`. /// with some expectation given by `source`.
pub fn note_source_of_type_mismatch_constraint( pub fn note_source_of_type_mismatch_constraint(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
source: TypeMismatchSource<'tcx>, source: TypeMismatchSource<'tcx>,
) -> bool { ) -> bool {
@ -550,7 +550,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// expected type. // expected type.
pub fn annotate_loop_expected_due_to_inference( pub fn annotate_loop_expected_due_to_inference(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
error: Option<TypeError<'tcx>>, error: Option<TypeError<'tcx>>,
) { ) {
@ -673,7 +673,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn annotate_expected_due_to_let_ty( fn annotate_expected_due_to_let_ty(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
error: Option<TypeError<'tcx>>, error: Option<TypeError<'tcx>>,
) { ) {
@ -782,7 +782,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn annotate_alternative_method_deref( fn annotate_alternative_method_deref(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
error: Option<TypeError<'tcx>>, error: Option<TypeError<'tcx>>,
) { ) {
@ -1029,7 +1029,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn explain_self_literal( fn explain_self_literal(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'tcx>, expr: &hir::Expr<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
found: Ty<'tcx>, found: Ty<'tcx>,
@ -1082,7 +1082,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn note_wrong_return_ty_due_to_generic_arg( fn note_wrong_return_ty_due_to_generic_arg(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
checked_ty: Ty<'tcx>, checked_ty: Ty<'tcx>,
) { ) {

View file

@ -3,8 +3,8 @@ use std::borrow::Cow;
use crate::fluent_generated as fluent; use crate::fluent_generated as fluent;
use rustc_errors::{ use rustc_errors::{
codes::*, AddToDiagnostic, Applicability, Diagnostic, DiagnosticArgValue, IntoDiagnosticArg, codes::*, AddToDiagnostic, Applicability, DiagnosticArgValue, DiagnosticBuilder,
MultiSpan, SubdiagnosticMessageOp, EmissionGuarantee, IntoDiagnosticArg, MultiSpan, SubdiagnosticMessageOp,
}; };
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
use rustc_middle::ty::Ty; use rustc_middle::ty::Ty;
@ -195,7 +195,11 @@ pub struct TypeMismatchFruTypo {
} }
impl AddToDiagnostic for TypeMismatchFruTypo { impl AddToDiagnostic for TypeMismatchFruTypo {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_f: F,
) {
diag.arg("expr", self.expr.as_deref().unwrap_or("NONE")); diag.arg("expr", self.expr.as_deref().unwrap_or("NONE"));
// Only explain that `a ..b` is a range if it's split up // Only explain that `a ..b` is a range if it's split up
@ -370,7 +374,11 @@ pub struct RemoveSemiForCoerce {
} }
impl AddToDiagnostic for RemoveSemiForCoerce { impl AddToDiagnostic for RemoveSemiForCoerce {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_f: F,
) {
let mut multispan: MultiSpan = self.semi.into(); let mut multispan: MultiSpan = self.semi.into();
multispan.push_span_label(self.expr, fluent::hir_typeck_remove_semi_for_coerce_expr); multispan.push_span_label(self.expr, fluent::hir_typeck_remove_semi_for_coerce_expr);
multispan.push_span_label(self.ret, fluent::hir_typeck_remove_semi_for_coerce_ret); multispan.push_span_label(self.ret, fluent::hir_typeck_remove_semi_for_coerce_ret);
@ -541,8 +549,12 @@ pub enum CastUnknownPointerSub {
From(Span), From(Span),
} }
impl AddToDiagnostic for CastUnknownPointerSub { impl rustc_errors::AddToDiagnostic for CastUnknownPointerSub {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, f: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
f: F,
) {
match self { match self {
CastUnknownPointerSub::To(span) => { CastUnknownPointerSub::To(span) => {
let msg = f(diag, crate::fluent_generated::hir_typeck_label_to); let msg = f(diag, crate::fluent_generated::hir_typeck_label_to);

View file

@ -26,8 +26,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_data_structures::unord::UnordMap; use rustc_data_structures::unord::UnordMap;
use rustc_errors::{ use rustc_errors::{
codes::*, pluralize, struct_span_code_err, AddToDiagnostic, Applicability, Diagnostic, codes::*, pluralize, struct_span_code_err, AddToDiagnostic, Applicability, DiagnosticBuilder,
DiagnosticBuilder, ErrorGuaranteed, StashKey, ErrorGuaranteed, StashKey,
}; };
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def::{CtorKind, DefKind, Res};
@ -69,7 +69,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self, &self,
expr: &'tcx hir::Expr<'tcx>, expr: &'tcx hir::Expr<'tcx>,
expected_ty: Ty<'tcx>, expected_ty: Ty<'tcx>,
extend_err: impl FnOnce(&mut Diagnostic), extend_err: impl FnOnce(&mut DiagnosticBuilder<'_>),
) -> Ty<'tcx> { ) -> Ty<'tcx> {
let mut ty = self.check_expr_with_expectation(expr, ExpectHasType(expected_ty)); let mut ty = self.check_expr_with_expectation(expr, ExpectHasType(expected_ty));
@ -958,7 +958,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
lhs: &'tcx hir::Expr<'tcx>, lhs: &'tcx hir::Expr<'tcx>,
code: ErrCode, code: ErrCode,
op_span: Span, op_span: Span,
adjust_err: impl FnOnce(&mut Diagnostic), adjust_err: impl FnOnce(&mut DiagnosticBuilder<'_>),
) { ) {
if lhs.is_syntactic_place_expr() { if lhs.is_syntactic_place_expr() {
return; return;
@ -1223,7 +1223,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let lhs_ty = self.check_expr_with_needs(lhs, Needs::MutPlace); let lhs_ty = self.check_expr_with_needs(lhs, Needs::MutPlace);
let suggest_deref_binop = |err: &mut Diagnostic, rhs_ty: Ty<'tcx>| { let suggest_deref_binop = |err: &mut DiagnosticBuilder<'_>, rhs_ty: Ty<'tcx>| {
if let Some(lhs_deref_ty) = self.deref_once_mutably_for_diagnostic(lhs_ty) { if let Some(lhs_deref_ty) = self.deref_once_mutably_for_diagnostic(lhs_ty) {
// Can only assign if the type is sized, so if `DerefMut` yields a type that is // Can only assign if the type is sized, so if `DerefMut` yields a type that is
// unsized, do not suggest dereferencing it. // unsized, do not suggest dereferencing it.
@ -2008,7 +2008,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
last_expr_field: &hir::ExprField<'tcx>, last_expr_field: &hir::ExprField<'tcx>,
variant: &ty::VariantDef, variant: &ty::VariantDef,
args: GenericArgsRef<'tcx>, args: GenericArgsRef<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
) { ) {
// I don't use 'is_range_literal' because only double-sided, half-open ranges count. // I don't use 'is_range_literal' because only double-sided, half-open ranges count.
if let ExprKind::Struct(QPath::LangItem(LangItem::Range, ..), [range_start, range_end], _) = if let ExprKind::Struct(QPath::LangItem(LangItem::Range, ..), [range_start, range_end], _) =
@ -2524,7 +2524,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn suggest_await_on_field_access( fn suggest_await_on_field_access(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
field_ident: Ident, field_ident: Ident,
base: &'tcx hir::Expr<'tcx>, base: &'tcx hir::Expr<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
@ -2723,7 +2723,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
err.emit() err.emit()
} }
fn point_at_param_definition(&self, err: &mut Diagnostic, param: ty::ParamTy) { fn point_at_param_definition(&self, err: &mut DiagnosticBuilder<'_>, param: ty::ParamTy) {
let generics = self.tcx.generics_of(self.body_id); let generics = self.tcx.generics_of(self.body_id);
let generic_param = generics.type_param(&param, self.tcx); let generic_param = generics.type_param(&param, self.tcx);
if let ty::GenericParamDefKind::Type { synthetic: true, .. } = generic_param.kind { if let ty::GenericParamDefKind::Type { synthetic: true, .. } = generic_param.kind {
@ -2742,7 +2742,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn maybe_suggest_array_indexing( fn maybe_suggest_array_indexing(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
base: &hir::Expr<'_>, base: &hir::Expr<'_>,
field: Ident, field: Ident,
@ -2766,7 +2766,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn suggest_first_deref_field( fn suggest_first_deref_field(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
base: &hir::Expr<'_>, base: &hir::Expr<'_>,
field: Ident, field: Ident,

View file

@ -5,7 +5,7 @@ use crate::rvalue_scopes;
use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LoweredTy}; use crate::{BreakableCtxt, Diverges, Expectation, FnCtxt, LoweredTy};
use rustc_data_structures::captures::Captures; use rustc_data_structures::captures::Captures;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{Applicability, Diagnostic, ErrorGuaranteed, MultiSpan, StashKey}; use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, StashKey};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def::{CtorOf, DefKind, Res};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
@ -1020,7 +1020,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(in super::super) fn note_internal_mutation_in_method( pub(in super::super) fn note_internal_mutation_in_method(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
expected: Option<Ty<'tcx>>, expected: Option<Ty<'tcx>>,
found: Ty<'tcx>, found: Ty<'tcx>,

View file

@ -13,7 +13,7 @@ use itertools::Itertools;
use rustc_ast as ast; use rustc_ast as ast;
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{ use rustc_errors::{
codes::*, pluralize, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan, StashKey, codes::*, pluralize, Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, StashKey,
}; };
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def::{CtorOf, DefKind, Res};
@ -1936,7 +1936,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn label_fn_like( fn label_fn_like(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
callable_def_id: Option<DefId>, callable_def_id: Option<DefId>,
callee_ty: Option<Ty<'tcx>>, callee_ty: Option<Ty<'tcx>>,
call_expr: &'tcx hir::Expr<'tcx>, call_expr: &'tcx hir::Expr<'tcx>,

View file

@ -12,7 +12,7 @@ use core::cmp::min;
use core::iter; use core::iter;
use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX}; use rustc_ast::util::parser::{ExprPrecedence, PREC_POSTFIX};
use rustc_data_structures::packed::Pu128; use rustc_data_structures::packed::Pu128;
use rustc_errors::{Applicability, Diagnostic, MultiSpan}; use rustc_errors::{Applicability, DiagnosticBuilder, MultiSpan};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::Res; use rustc_hir::def::Res;
use rustc_hir::def::{CtorKind, CtorOf, DefKind}; use rustc_hir::def::{CtorKind, CtorOf, DefKind};
@ -48,7 +48,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
.copied() .copied()
} }
pub(in super::super) fn suggest_semicolon_at_end(&self, span: Span, err: &mut Diagnostic) { pub(in super::super) fn suggest_semicolon_at_end(
&self,
span: Span,
err: &mut DiagnosticBuilder<'_>,
) {
// This suggestion is incorrect for // This suggestion is incorrect for
// fn foo() -> bool { match () { () => true } || match () { () => true } } // fn foo() -> bool { match () { () => true } || match () { () => true } }
err.span_suggestion_short( err.span_suggestion_short(
@ -66,7 +70,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// - Possible missing return type if the return type is the default, and not `fn main()`. /// - Possible missing return type if the return type is the default, and not `fn main()`.
pub fn suggest_mismatched_types_on_tail( pub fn suggest_mismatched_types_on_tail(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &'tcx hir::Expr<'tcx>, expr: &'tcx hir::Expr<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
found: Ty<'tcx>, found: Ty<'tcx>,
@ -97,7 +101,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// ``` /// ```
pub(crate) fn suggest_fn_call( pub(crate) fn suggest_fn_call(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
found: Ty<'tcx>, found: Ty<'tcx>,
can_satisfy: impl FnOnce(Ty<'tcx>) -> bool, can_satisfy: impl FnOnce(Ty<'tcx>) -> bool,
@ -179,7 +183,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub fn suggest_two_fn_call( pub fn suggest_two_fn_call(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
lhs_expr: &'tcx hir::Expr<'tcx>, lhs_expr: &'tcx hir::Expr<'tcx>,
lhs_ty: Ty<'tcx>, lhs_ty: Ty<'tcx>,
rhs_expr: &'tcx hir::Expr<'tcx>, rhs_expr: &'tcx hir::Expr<'tcx>,
@ -253,7 +257,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub fn suggest_remove_last_method_call( pub fn suggest_remove_last_method_call(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'tcx>, expr: &hir::Expr<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
) -> bool { ) -> bool {
@ -282,7 +286,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub fn suggest_deref_ref_or_into( pub fn suggest_deref_ref_or_into(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'tcx>, expr: &hir::Expr<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
found: Ty<'tcx>, found: Ty<'tcx>,
@ -540,7 +544,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// in the heap by calling `Box::new()`. /// in the heap by calling `Box::new()`.
pub(in super::super) fn suggest_boxing_when_appropriate( pub(in super::super) fn suggest_boxing_when_appropriate(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
span: Span, span: Span,
hir_id: HirId, hir_id: HirId,
expected: Ty<'tcx>, expected: Ty<'tcx>,
@ -583,7 +587,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// suggest a non-capturing closure /// suggest a non-capturing closure
pub(in super::super) fn suggest_no_capture_closure( pub(in super::super) fn suggest_no_capture_closure(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
found: Ty<'tcx>, found: Ty<'tcx>,
) -> bool { ) -> bool {
@ -620,7 +624,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
#[instrument(skip(self, err))] #[instrument(skip(self, err))]
pub(in super::super) fn suggest_calling_boxed_future_when_appropriate( pub(in super::super) fn suggest_calling_boxed_future_when_appropriate(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
found: Ty<'tcx>, found: Ty<'tcx>,
@ -732,7 +736,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// block is needed to be added too (`|| { expr; }`). This is denoted by `needs_block`. /// block is needed to be added too (`|| { expr; }`). This is denoted by `needs_block`.
pub fn suggest_missing_semicolon( pub fn suggest_missing_semicolon(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expression: &'tcx hir::Expr<'tcx>, expression: &'tcx hir::Expr<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
needs_block: bool, needs_block: bool,
@ -791,7 +795,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
#[instrument(level = "trace", skip(self, err))] #[instrument(level = "trace", skip(self, err))]
pub(in super::super) fn suggest_missing_return_type( pub(in super::super) fn suggest_missing_return_type(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
fn_decl: &hir::FnDecl<'tcx>, fn_decl: &hir::FnDecl<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
found: Ty<'tcx>, found: Ty<'tcx>,
@ -909,7 +913,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// ``` /// ```
fn try_suggest_return_impl_trait( fn try_suggest_return_impl_trait(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
found: Ty<'tcx>, found: Ty<'tcx>,
fn_id: hir::HirId, fn_id: hir::HirId,
@ -1014,7 +1018,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(in super::super) fn suggest_missing_break_or_return_expr( pub(in super::super) fn suggest_missing_break_or_return_expr(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &'tcx hir::Expr<'tcx>, expr: &'tcx hir::Expr<'tcx>,
fn_decl: &hir::FnDecl<'tcx>, fn_decl: &hir::FnDecl<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
@ -1118,7 +1122,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(in super::super) fn suggest_missing_parentheses( pub(in super::super) fn suggest_missing_parentheses(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
) -> bool { ) -> bool {
let sp = self.tcx.sess.source_map().start_point(expr.span).with_parent(None); let sp = self.tcx.sess.source_map().start_point(expr.span).with_parent(None);
@ -1136,7 +1140,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// if it was possibly mistaken array syntax. /// if it was possibly mistaken array syntax.
pub(crate) fn suggest_block_to_brackets_peeling_refs( pub(crate) fn suggest_block_to_brackets_peeling_refs(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
mut expr: &hir::Expr<'_>, mut expr: &hir::Expr<'_>,
mut expr_ty: Ty<'tcx>, mut expr_ty: Ty<'tcx>,
mut expected_ty: Ty<'tcx>, mut expected_ty: Ty<'tcx>,
@ -1163,7 +1167,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(crate) fn suggest_clone_for_ref( pub(crate) fn suggest_clone_for_ref(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
expr_ty: Ty<'tcx>, expr_ty: Ty<'tcx>,
expected_ty: Ty<'tcx>, expected_ty: Ty<'tcx>,
@ -1198,7 +1202,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(crate) fn suggest_copied_cloned_or_as_ref( pub(crate) fn suggest_copied_cloned_or_as_ref(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
expr_ty: Ty<'tcx>, expr_ty: Ty<'tcx>,
expected_ty: Ty<'tcx>, expected_ty: Ty<'tcx>,
@ -1248,7 +1252,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(crate) fn suggest_into( pub(crate) fn suggest_into(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
expr_ty: Ty<'tcx>, expr_ty: Ty<'tcx>,
expected_ty: Ty<'tcx>, expected_ty: Ty<'tcx>,
@ -1311,7 +1315,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// When expecting a `bool` and finding an `Option`, suggests using `let Some(..)` or `.is_some()` /// When expecting a `bool` and finding an `Option`, suggests using `let Some(..)` or `.is_some()`
pub(crate) fn suggest_option_to_bool( pub(crate) fn suggest_option_to_bool(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
expr_ty: Ty<'tcx>, expr_ty: Ty<'tcx>,
expected_ty: Ty<'tcx>, expected_ty: Ty<'tcx>,
@ -1368,7 +1372,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// in case the block was mistaken array syntax, e.g. `{ 1 }` -> `[ 1 ]`. /// in case the block was mistaken array syntax, e.g. `{ 1 }` -> `[ 1 ]`.
pub(crate) fn suggest_block_to_brackets( pub(crate) fn suggest_block_to_brackets(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
blk: &hir::Block<'_>, blk: &hir::Block<'_>,
blk_ty: Ty<'tcx>, blk_ty: Ty<'tcx>,
expected_ty: Ty<'tcx>, expected_ty: Ty<'tcx>,
@ -1408,7 +1412,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
#[instrument(skip(self, err))] #[instrument(skip(self, err))]
pub(crate) fn suggest_floating_point_literal( pub(crate) fn suggest_floating_point_literal(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
expected_ty: Ty<'tcx>, expected_ty: Ty<'tcx>,
) -> bool { ) -> bool {
@ -1479,7 +1483,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
#[instrument(skip(self, err))] #[instrument(skip(self, err))]
pub(crate) fn suggest_null_ptr_for_literal_zero_given_to_ptr_arg( pub(crate) fn suggest_null_ptr_for_literal_zero_given_to_ptr_arg(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
expected_ty: Ty<'tcx>, expected_ty: Ty<'tcx>,
) -> bool { ) -> bool {
@ -1517,7 +1521,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(crate) fn suggest_associated_const( pub(crate) fn suggest_associated_const(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'tcx>, expr: &hir::Expr<'tcx>,
expected_ty: Ty<'tcx>, expected_ty: Ty<'tcx>,
) -> bool { ) -> bool {
@ -1611,7 +1615,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// which is a side-effect of autoref. /// which is a side-effect of autoref.
pub(crate) fn note_type_is_not_clone( pub(crate) fn note_type_is_not_clone(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
expected_ty: Ty<'tcx>, expected_ty: Ty<'tcx>,
found_ty: Ty<'tcx>, found_ty: Ty<'tcx>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
@ -1811,7 +1815,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
&self, &self,
blk: &'tcx hir::Block<'tcx>, blk: &'tcx hir::Block<'tcx>,
expected_ty: Ty<'tcx>, expected_ty: Ty<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
) -> bool { ) -> bool {
if let Some((span_semi, boxed)) = self.err_ctxt().could_remove_semicolon(blk, expected_ty) { if let Some((span_semi, boxed)) = self.err_ctxt().could_remove_semicolon(blk, expected_ty) {
if let StatementAsExpression::NeedsBoxing = boxed { if let StatementAsExpression::NeedsBoxing = boxed {
@ -1856,7 +1860,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(crate) fn suggest_missing_unwrap_expect( pub(crate) fn suggest_missing_unwrap_expect(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'tcx>, expr: &hir::Expr<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
found: Ty<'tcx>, found: Ty<'tcx>,
@ -1939,7 +1943,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(crate) fn suggest_coercing_result_via_try_operator( pub(crate) fn suggest_coercing_result_via_try_operator(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'tcx>, expr: &hir::Expr<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
found: Ty<'tcx>, found: Ty<'tcx>,
@ -1986,7 +1990,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// sole field is of the found type, suggest such variants. (Issue #42764) /// sole field is of the found type, suggest such variants. (Issue #42764)
pub(crate) fn suggest_compatible_variants( pub(crate) fn suggest_compatible_variants(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
expr_ty: Ty<'tcx>, expr_ty: Ty<'tcx>,
@ -2175,7 +2179,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(crate) fn suggest_non_zero_new_unwrap( pub(crate) fn suggest_non_zero_new_unwrap(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
expr_ty: Ty<'tcx>, expr_ty: Ty<'tcx>,
@ -2719,7 +2723,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(crate) fn suggest_cast( pub(crate) fn suggest_cast(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
checked_ty: Ty<'tcx>, checked_ty: Ty<'tcx>,
expected_ty: Ty<'tcx>, expected_ty: Ty<'tcx>,
@ -2847,7 +2851,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let in_const_context = self.tcx.hir().is_inside_const_context(expr.hir_id); let in_const_context = self.tcx.hir().is_inside_const_context(expr.hir_id);
let suggest_fallible_into_or_lhs_from = let suggest_fallible_into_or_lhs_from =
|err: &mut Diagnostic, exp_to_found_is_fallible: bool| { |err: &mut DiagnosticBuilder<'_>, exp_to_found_is_fallible: bool| {
// If we know the expression the expected type is derived from, we might be able // If we know the expression the expected type is derived from, we might be able
// to suggest a widening conversion rather than a narrowing one (which may // to suggest a widening conversion rather than a narrowing one (which may
// panic). For example, given x: u8 and y: u32, if we know the span of "x", // panic). For example, given x: u8 and y: u32, if we know the span of "x",
@ -2887,7 +2891,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}; };
let suggest_to_change_suffix_or_into = let suggest_to_change_suffix_or_into =
|err: &mut Diagnostic, |err: &mut DiagnosticBuilder<'_>,
found_to_exp_is_fallible: bool, found_to_exp_is_fallible: bool,
exp_to_found_is_fallible: bool| { exp_to_found_is_fallible: bool| {
let exp_is_lhs = expected_ty_expr.is_some_and(|e| self.tcx.hir().is_lhs(e.hir_id)); let exp_is_lhs = expected_ty_expr.is_some_and(|e| self.tcx.hir().is_lhs(e.hir_id));
@ -3085,7 +3089,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Identify when the user has written `foo..bar()` instead of `foo.bar()`. /// Identify when the user has written `foo..bar()` instead of `foo.bar()`.
pub(crate) fn suggest_method_call_on_range_literal( pub(crate) fn suggest_method_call_on_range_literal(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'tcx>, expr: &hir::Expr<'tcx>,
checked_ty: Ty<'tcx>, checked_ty: Ty<'tcx>,
expected_ty: Ty<'tcx>, expected_ty: Ty<'tcx>,
@ -3163,7 +3167,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// block without a tail expression. /// block without a tail expression.
pub(crate) fn suggest_return_binding_for_missing_tail_expr( pub(crate) fn suggest_return_binding_for_missing_tail_expr(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
checked_ty: Ty<'tcx>, checked_ty: Ty<'tcx>,
expected_ty: Ty<'tcx>, expected_ty: Ty<'tcx>,

View file

@ -11,7 +11,7 @@ pub use self::suggest::SelfSource;
pub use self::MethodError::*; pub use self::MethodError::*;
use crate::FnCtxt; use crate::FnCtxt;
use rustc_errors::{Applicability, Diagnostic, SubdiagnosticMessage}; use rustc_errors::{Applicability, DiagnosticBuilder, SubdiagnosticMessage};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{CtorOf, DefKind, Namespace}; use rustc_hir::def::{CtorOf, DefKind, Namespace};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
@ -126,7 +126,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
#[instrument(level = "debug", skip(self, err, call_expr))] #[instrument(level = "debug", skip(self, err, call_expr))]
pub(crate) fn suggest_method_call( pub(crate) fn suggest_method_call(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
msg: impl Into<SubdiagnosticMessage> + std::fmt::Debug, msg: impl Into<SubdiagnosticMessage> + std::fmt::Debug,
method_name: Ident, method_name: Ident,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,

View file

@ -12,8 +12,8 @@ use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::sorted_map::SortedMap;
use rustc_data_structures::unord::UnordSet; use rustc_data_structures::unord::UnordSet;
use rustc_errors::{ use rustc_errors::{
codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, codes::*, pluralize, struct_span_code_err, Applicability, DiagnosticBuilder, MultiSpan,
MultiSpan, StashKey, StashKey,
}; };
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
@ -1127,7 +1127,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
let label_span_not_found = |err: &mut Diagnostic| { let label_span_not_found = |err: &mut DiagnosticBuilder<'_>| {
if unsatisfied_predicates.is_empty() { if unsatisfied_predicates.is_empty() {
err.span_label(span, format!("{item_kind} not found in `{ty_str}`")); err.span_label(span, format!("{item_kind} not found in `{ty_str}`"));
let is_string_or_ref_str = match rcvr_ty.kind() { let is_string_or_ref_str = match rcvr_ty.kind() {
@ -1438,7 +1438,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self_source: SelfSource<'tcx>, self_source: SelfSource<'tcx>,
args: Option<&'tcx [hir::Expr<'tcx>]>, args: Option<&'tcx [hir::Expr<'tcx>]>,
span: Span, span: Span,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
sources: &mut Vec<CandidateSource>, sources: &mut Vec<CandidateSource>,
sugg_span: Option<Span>, sugg_span: Option<Span>,
) { ) {
@ -1584,7 +1584,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Look at all the associated functions without receivers in the type's inherent impls /// Look at all the associated functions without receivers in the type's inherent impls
/// to look for builders that return `Self`, `Option<Self>` or `Result<Self, _>`. /// to look for builders that return `Self`, `Option<Self>` or `Result<Self, _>`.
fn find_builder_fn(&self, err: &mut Diagnostic, rcvr_ty: Ty<'tcx>) { fn find_builder_fn(&self, err: &mut DiagnosticBuilder<'_>, rcvr_ty: Ty<'tcx>) {
let ty::Adt(adt_def, _) = rcvr_ty.kind() else { let ty::Adt(adt_def, _) = rcvr_ty.kind() else {
return; return;
}; };
@ -1665,7 +1665,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// doesn't take a `self` receiver. /// doesn't take a `self` receiver.
fn suggest_associated_call_syntax( fn suggest_associated_call_syntax(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
static_candidates: &Vec<CandidateSource>, static_candidates: &Vec<CandidateSource>,
rcvr_ty: Ty<'tcx>, rcvr_ty: Ty<'tcx>,
source: SelfSource<'tcx>, source: SelfSource<'tcx>,
@ -1809,7 +1809,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
rcvr_ty: Ty<'tcx>, rcvr_ty: Ty<'tcx>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
item_name: Ident, item_name: Ident,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
) -> bool { ) -> bool {
let tcx = self.tcx; let tcx = self.tcx;
let field_receiver = self.autoderef(span, rcvr_ty).find_map(|(ty, _)| match ty.kind() { let field_receiver = self.autoderef(span, rcvr_ty).find_map(|(ty, _)| match ty.kind() {
@ -2132,7 +2132,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Suggest calling a method on a field i.e. `a.field.bar()` instead of `a.bar()` /// Suggest calling a method on a field i.e. `a.field.bar()` instead of `a.bar()`
fn suggest_calling_method_on_field( fn suggest_calling_method_on_field(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
source: SelfSource<'tcx>, source: SelfSource<'tcx>,
span: Span, span: Span,
actual: Ty<'tcx>, actual: Ty<'tcx>,
@ -2212,7 +2212,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn suggest_unwrapping_inner_self( fn suggest_unwrapping_inner_self(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
source: SelfSource<'tcx>, source: SelfSource<'tcx>,
actual: Ty<'tcx>, actual: Ty<'tcx>,
item_name: Ident, item_name: Ident,
@ -2401,7 +2401,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(crate) fn note_unmet_impls_on_type( pub(crate) fn note_unmet_impls_on_type(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
errors: Vec<FulfillmentError<'tcx>>, errors: Vec<FulfillmentError<'tcx>>,
suggest_derive: bool, suggest_derive: bool,
) { ) {
@ -2484,7 +2484,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn note_predicate_source_and_get_derives( fn note_predicate_source_and_get_derives(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
unsatisfied_predicates: &[( unsatisfied_predicates: &[(
ty::Predicate<'tcx>, ty::Predicate<'tcx>,
Option<ty::Predicate<'tcx>>, Option<ty::Predicate<'tcx>>,
@ -2566,7 +2566,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
pub(crate) fn suggest_derive( pub(crate) fn suggest_derive(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
unsatisfied_predicates: &[( unsatisfied_predicates: &[(
ty::Predicate<'tcx>, ty::Predicate<'tcx>,
Option<ty::Predicate<'tcx>>, Option<ty::Predicate<'tcx>>,
@ -2602,7 +2602,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn note_derefed_ty_has_method( fn note_derefed_ty_has_method(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
self_source: SelfSource<'tcx>, self_source: SelfSource<'tcx>,
rcvr_ty: Ty<'tcx>, rcvr_ty: Ty<'tcx>,
item_name: Ident, item_name: Ident,
@ -2682,7 +2682,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn suggest_await_before_method( fn suggest_await_before_method(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
item_name: Ident, item_name: Ident,
ty: Ty<'tcx>, ty: Ty<'tcx>,
call: &hir::Expr<'_>, call: &hir::Expr<'_>,
@ -2705,7 +2705,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
} }
fn suggest_use_candidates(&self, err: &mut Diagnostic, msg: String, candidates: Vec<DefId>) { fn suggest_use_candidates(
&self,
err: &mut DiagnosticBuilder<'_>,
msg: String,
candidates: Vec<DefId>,
) {
let parent_map = self.tcx.visible_parent_map(()); let parent_map = self.tcx.visible_parent_map(());
// Separate out candidates that must be imported with a glob, because they are named `_` // Separate out candidates that must be imported with a glob, because they are named `_`
@ -2752,7 +2757,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn suggest_valid_traits( fn suggest_valid_traits(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
valid_out_of_scope_traits: Vec<DefId>, valid_out_of_scope_traits: Vec<DefId>,
explain: bool, explain: bool,
) -> bool { ) -> bool {
@ -2793,7 +2798,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn suggest_traits_to_import( fn suggest_traits_to_import(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
span: Span, span: Span,
rcvr_ty: Ty<'tcx>, rcvr_ty: Ty<'tcx>,
item_name: Ident, item_name: Ident,
@ -3332,7 +3337,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// FIXME: currently not working for suggesting `map_or_else`, see #102408 /// FIXME: currently not working for suggesting `map_or_else`, see #102408
pub(crate) fn suggest_else_fn_with_closure( pub(crate) fn suggest_else_fn_with_closure(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
found: Ty<'tcx>, found: Ty<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
@ -3458,7 +3463,7 @@ pub fn all_traits(tcx: TyCtxt<'_>) -> Vec<TraitInfo> {
fn print_disambiguation_help<'tcx>( fn print_disambiguation_help<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
source: SelfSource<'tcx>, source: SelfSource<'tcx>,
args: Option<&'tcx [hir::Expr<'tcx>]>, args: Option<&'tcx [hir::Expr<'tcx>]>,
trait_ref: ty::TraitRef<'tcx>, trait_ref: ty::TraitRef<'tcx>,

View file

@ -5,7 +5,7 @@ use super::FnCtxt;
use crate::Expectation; use crate::Expectation;
use rustc_ast as ast; use rustc_ast as ast;
use rustc_data_structures::packed::Pu128; use rustc_data_structures::packed::Pu128;
use rustc_errors::{codes::*, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder}; use rustc_errors::{codes::*, struct_span_code_err, Applicability, DiagnosticBuilder};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind}; use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::traits::ObligationCauseCode; use rustc_infer::traits::ObligationCauseCode;
@ -695,7 +695,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
rhs_expr: &'tcx hir::Expr<'tcx>, rhs_expr: &'tcx hir::Expr<'tcx>,
lhs_ty: Ty<'tcx>, lhs_ty: Ty<'tcx>,
rhs_ty: Ty<'tcx>, rhs_ty: Ty<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
is_assign: IsAssign, is_assign: IsAssign,
op: hir::BinOp, op: hir::BinOp,
) -> bool { ) -> bool {

View file

@ -3,8 +3,8 @@ use crate::{errors, FnCtxt, LoweredTy};
use rustc_ast as ast; use rustc_ast as ast;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{ use rustc_errors::{
codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, codes::*, pluralize, struct_span_code_err, Applicability, DiagnosticBuilder, ErrorGuaranteed,
ErrorGuaranteed, MultiSpan, MultiSpan,
}; };
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::def::{CtorKind, DefKind, Res};
@ -529,7 +529,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty ty
} }
fn endpoint_has_type(&self, err: &mut Diagnostic, span: Span, ty: Ty<'_>) { fn endpoint_has_type(&self, err: &mut DiagnosticBuilder<'_>, span: Span, ty: Ty<'_>) {
if !ty.references_error() { if !ty.references_error() {
err.span_label(span, format!("this is of type `{ty}`")); err.span_label(span, format!("this is of type `{ty}`"));
} }
@ -683,7 +683,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn suggest_adding_missing_ref_or_removing_ref( fn suggest_adding_missing_ref_or_removing_ref(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
span: Span, span: Span,
expected: Ty<'tcx>, expected: Ty<'tcx>,
actual: Ty<'tcx>, actual: Ty<'tcx>,
@ -715,7 +715,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
// Precondition: pat is a Ref(_) pattern // Precondition: pat is a Ref(_) pattern
fn borrow_pat_suggestion(&self, err: &mut Diagnostic, pat: &Pat<'_>) { fn borrow_pat_suggestion(&self, err: &mut DiagnosticBuilder<'_>, pat: &Pat<'_>) {
let tcx = self.tcx; let tcx = self.tcx;
if let PatKind::Ref(inner, mutbl) = pat.kind if let PatKind::Ref(inner, mutbl) = pat.kind
&& let PatKind::Binding(_, _, binding, ..) = inner.kind && let PatKind::Binding(_, _, binding, ..) = inner.kind
@ -933,7 +933,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn maybe_suggest_range_literal( fn maybe_suggest_range_literal(
&self, &self,
e: &mut Diagnostic, e: &mut DiagnosticBuilder<'_>,
opt_def_id: Option<hir::def_id::DefId>, opt_def_id: Option<hir::def_id::DefId>,
ident: Ident, ident: Ident,
) -> bool { ) -> bool {

View file

@ -1,7 +1,8 @@
use hir::GenericParamKind; use hir::GenericParamKind;
use rustc_errors::{ use rustc_errors::{
codes::*, AddToDiagnostic, Applicability, Diagnostic, DiagnosticMessage, codes::*, AddToDiagnostic, Applicability, DiagnosticBuilder, DiagnosticMessage,
DiagnosticStyledString, IntoDiagnosticArg, MultiSpan, SubdiagnosticMessageOp, DiagnosticStyledString, EmissionGuarantee, IntoDiagnosticArg, MultiSpan,
SubdiagnosticMessageOp,
}; };
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::FnRetTy; use rustc_hir::FnRetTy;
@ -225,7 +226,11 @@ pub enum RegionOriginNote<'a> {
} }
impl AddToDiagnostic for RegionOriginNote<'_> { impl AddToDiagnostic for RegionOriginNote<'_> {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_f: F,
) {
let mut label_or_note = |span, msg: DiagnosticMessage| { let mut label_or_note = |span, msg: DiagnosticMessage| {
let sub_count = diag.children.iter().filter(|d| d.span.is_dummy()).count(); let sub_count = diag.children.iter().filter(|d| d.span.is_dummy()).count();
let expanded_sub_count = diag.children.iter().filter(|d| !d.span.is_dummy()).count(); let expanded_sub_count = diag.children.iter().filter(|d| !d.span.is_dummy()).count();
@ -286,7 +291,11 @@ pub enum LifetimeMismatchLabels {
} }
impl AddToDiagnostic for LifetimeMismatchLabels { impl AddToDiagnostic for LifetimeMismatchLabels {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_f: F,
) {
match self { match self {
LifetimeMismatchLabels::InRet { param_span, ret_span, span, label_var1 } => { LifetimeMismatchLabels::InRet { param_span, ret_span, span, label_var1 } => {
diag.span_label(param_span, fluent::infer_declared_different); diag.span_label(param_span, fluent::infer_declared_different);
@ -330,7 +339,11 @@ pub struct AddLifetimeParamsSuggestion<'a> {
} }
impl AddToDiagnostic for AddLifetimeParamsSuggestion<'_> { impl AddToDiagnostic for AddLifetimeParamsSuggestion<'_> {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_f: F,
) {
let mut mk_suggestion = || { let mut mk_suggestion = || {
let ( let (
hir::Ty { kind: hir::TyKind::Ref(lifetime_sub, _), .. }, hir::Ty { kind: hir::TyKind::Ref(lifetime_sub, _), .. },
@ -428,7 +441,11 @@ pub struct IntroducesStaticBecauseUnmetLifetimeReq {
} }
impl AddToDiagnostic for IntroducesStaticBecauseUnmetLifetimeReq { impl AddToDiagnostic for IntroducesStaticBecauseUnmetLifetimeReq {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(mut self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
mut self,
diag: &mut DiagnosticBuilder<'_, G>,
_f: F,
) {
self.unmet_requirements self.unmet_requirements
.push_span_label(self.binding_span, fluent::infer_msl_introduces_static); .push_span_label(self.binding_span, fluent::infer_msl_introduces_static);
diag.span_note(self.unmet_requirements, fluent::infer_msl_unmet_req); diag.span_note(self.unmet_requirements, fluent::infer_msl_unmet_req);
@ -743,7 +760,11 @@ pub struct ConsiderBorrowingParamHelp {
} }
impl AddToDiagnostic for ConsiderBorrowingParamHelp { impl AddToDiagnostic for ConsiderBorrowingParamHelp {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, f: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
f: F,
) {
let mut type_param_span: MultiSpan = self.spans.clone().into(); let mut type_param_span: MultiSpan = self.spans.clone().into();
for &span in &self.spans { for &span in &self.spans {
// Seems like we can't call f() here as Into<DiagnosticMessage> is required // Seems like we can't call f() here as Into<DiagnosticMessage> is required
@ -784,7 +805,11 @@ pub struct DynTraitConstraintSuggestion {
} }
impl AddToDiagnostic for DynTraitConstraintSuggestion { impl AddToDiagnostic for DynTraitConstraintSuggestion {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, f: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
f: F,
) {
let mut multi_span: MultiSpan = vec![self.span].into(); let mut multi_span: MultiSpan = vec![self.span].into();
multi_span.push_span_label(self.span, fluent::infer_dtcs_has_lifetime_req_label); multi_span.push_span_label(self.span, fluent::infer_dtcs_has_lifetime_req_label);
multi_span.push_span_label(self.ident.span, fluent::infer_dtcs_introduces_requirement); multi_span.push_span_label(self.ident.span, fluent::infer_dtcs_introduces_requirement);
@ -827,7 +852,11 @@ pub struct ReqIntroducedLocations {
} }
impl AddToDiagnostic for ReqIntroducedLocations { impl AddToDiagnostic for ReqIntroducedLocations {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(mut self, diag: &mut Diagnostic, f: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
mut self,
diag: &mut DiagnosticBuilder<'_, G>,
f: F,
) {
for sp in self.spans { for sp in self.spans {
self.span.push_span_label(sp, fluent::infer_ril_introduced_here); self.span.push_span_label(sp, fluent::infer_ril_introduced_here);
} }
@ -846,7 +875,11 @@ pub struct MoreTargeted {
} }
impl AddToDiagnostic for MoreTargeted { impl AddToDiagnostic for MoreTargeted {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _f: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_f: F,
) {
diag.code(E0772); diag.code(E0772);
diag.primary_message(fluent::infer_more_targeted); diag.primary_message(fluent::infer_more_targeted);
diag.arg("ident", self.ident); diag.arg("ident", self.ident);
@ -1265,7 +1298,11 @@ pub struct SuggestTuplePatternMany {
} }
impl AddToDiagnostic for SuggestTuplePatternMany { impl AddToDiagnostic for SuggestTuplePatternMany {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, f: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
f: F,
) {
diag.arg("path", self.path); diag.arg("path", self.path);
let message = f(diag, crate::fluent_generated::infer_stp_wrap_many.into()); let message = f(diag, crate::fluent_generated::infer_stp_wrap_many.into());
diag.multipart_suggestions( diag.multipart_suggestions(

View file

@ -1,6 +1,9 @@
use crate::fluent_generated as fluent; use crate::fluent_generated as fluent;
use crate::infer::error_reporting::nice_region_error::find_anon_type; use crate::infer::error_reporting::nice_region_error::find_anon_type;
use rustc_errors::{AddToDiagnostic, Diagnostic, IntoDiagnosticArg, SubdiagnosticMessageOp}; use rustc_errors::{
AddToDiagnostic, DiagnosticBuilder, EmissionGuarantee, IntoDiagnosticArg,
SubdiagnosticMessageOp,
};
use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::ty::{self, TyCtxt};
use rustc_span::{symbol::kw, Span}; use rustc_span::{symbol::kw, Span};
@ -160,7 +163,11 @@ impl RegionExplanation<'_> {
} }
impl AddToDiagnostic for RegionExplanation<'_> { impl AddToDiagnostic for RegionExplanation<'_> {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, f: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
f: F,
) {
diag.arg("pref_kind", self.prefix); diag.arg("pref_kind", self.prefix);
diag.arg("suff_kind", self.suffix); diag.arg("suff_kind", self.suffix);
diag.arg("desc_kind", self.desc.kind); diag.arg("desc_kind", self.desc.kind);

View file

@ -60,8 +60,8 @@ use crate::traits::{
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_errors::{ use rustc_errors::{
codes::*, pluralize, struct_span_code_err, Applicability, DiagCtxt, Diagnostic, codes::*, pluralize, struct_span_code_err, Applicability, DiagCtxt, DiagnosticBuilder,
DiagnosticBuilder, DiagnosticStyledString, ErrorGuaranteed, IntoDiagnosticArg, DiagnosticStyledString, ErrorGuaranteed, IntoDiagnosticArg,
}; };
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
@ -155,7 +155,7 @@ impl<'tcx> Deref for TypeErrCtxt<'_, 'tcx> {
pub(super) fn note_and_explain_region<'tcx>( pub(super) fn note_and_explain_region<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
prefix: &str, prefix: &str,
region: ty::Region<'tcx>, region: ty::Region<'tcx>,
suffix: &str, suffix: &str,
@ -180,7 +180,7 @@ pub(super) fn note_and_explain_region<'tcx>(
fn explain_free_region<'tcx>( fn explain_free_region<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
prefix: &str, prefix: &str,
region: ty::Region<'tcx>, region: ty::Region<'tcx>,
suffix: &str, suffix: &str,
@ -262,7 +262,7 @@ fn msg_span_from_named_region<'tcx>(
} }
fn emit_msg_span( fn emit_msg_span(
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
prefix: &str, prefix: &str,
description: String, description: String,
span: Option<Span>, span: Option<Span>,
@ -278,7 +278,7 @@ fn emit_msg_span(
} }
fn label_msg_span( fn label_msg_span(
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
prefix: &str, prefix: &str,
description: String, description: String,
span: Option<Span>, span: Option<Span>,
@ -577,7 +577,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
/// Adds a note if the types come from similarly named crates /// Adds a note if the types come from similarly named crates
fn check_and_note_conflicting_crates(&self, err: &mut Diagnostic, terr: TypeError<'tcx>) { fn check_and_note_conflicting_crates(
&self,
err: &mut DiagnosticBuilder<'_>,
terr: TypeError<'tcx>,
) {
use hir::def_id::CrateNum; use hir::def_id::CrateNum;
use rustc_hir::definitions::DisambiguatedDefPathData; use rustc_hir::definitions::DisambiguatedDefPathData;
use ty::print::Printer; use ty::print::Printer;
@ -651,7 +655,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
} }
let report_path_match = |err: &mut Diagnostic, did1: DefId, did2: DefId| { let report_path_match = |err: &mut DiagnosticBuilder<'_>, did1: DefId, did2: DefId| {
// Only report definitions from different crates. If both definitions // Only report definitions from different crates. If both definitions
// are from a local module we could have false positives, e.g. // are from a local module we could have false positives, e.g.
// let _ = [{struct Foo; Foo}, {struct Foo; Foo}]; // let _ = [{struct Foo; Foo}, {struct Foo; Foo}];
@ -701,7 +705,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn note_error_origin( fn note_error_origin(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
exp_found: Option<ty::error::ExpectedFound<Ty<'tcx>>>, exp_found: Option<ty::error::ExpectedFound<Ty<'tcx>>>,
terr: TypeError<'tcx>, terr: TypeError<'tcx>,
@ -1535,7 +1539,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
)] )]
pub fn note_type_err( pub fn note_type_err(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
secondary_span: Option<(Span, Cow<'static, str>)>, secondary_span: Option<(Span, Cow<'static, str>)>,
mut values: Option<ValuePairs<'tcx>>, mut values: Option<ValuePairs<'tcx>>,
@ -1582,14 +1586,14 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
types_visitor types_visitor
} }
fn report(&self, err: &mut Diagnostic) { fn report(&self, err: &mut DiagnosticBuilder<'_>) {
self.add_labels_for_types(err, "expected", &self.expected); self.add_labels_for_types(err, "expected", &self.expected);
self.add_labels_for_types(err, "found", &self.found); self.add_labels_for_types(err, "found", &self.found);
} }
fn add_labels_for_types( fn add_labels_for_types(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
target: &str, target: &str,
types: &FxIndexMap<TyCategory, FxIndexSet<Span>>, types: &FxIndexMap<TyCategory, FxIndexSet<Span>>,
) { ) {
@ -1803,7 +1807,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|prim: Ty<'tcx>, |prim: Ty<'tcx>,
shadow: Ty<'tcx>, shadow: Ty<'tcx>,
defid: DefId, defid: DefId,
diagnostic: &mut Diagnostic| { diagnostic: &mut DiagnosticBuilder<'_>| {
let name = shadow.sort_string(self.tcx); let name = shadow.sort_string(self.tcx);
diagnostic.note(format!( diagnostic.note(format!(
"{prim} and {name} have similar names, but are actually distinct types" "{prim} and {name} have similar names, but are actually distinct types"
@ -1823,7 +1827,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
let diagnose_adts = let diagnose_adts =
|expected_adt: ty::AdtDef<'tcx>, |expected_adt: ty::AdtDef<'tcx>,
found_adt: ty::AdtDef<'tcx>, found_adt: ty::AdtDef<'tcx>,
diagnostic: &mut Diagnostic| { diagnostic: &mut DiagnosticBuilder<'_>| {
let found_name = values.found.sort_string(self.tcx); let found_name = values.found.sort_string(self.tcx);
let expected_name = values.expected.sort_string(self.tcx); let expected_name = values.expected.sort_string(self.tcx);

View file

@ -12,7 +12,7 @@ use crate::infer::SubregionOrigin;
use crate::infer::TyCtxt; use crate::infer::TyCtxt;
use rustc_errors::AddToDiagnostic; use rustc_errors::AddToDiagnostic;
use rustc_errors::{Diagnostic, ErrorGuaranteed}; use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
use rustc_hir::Ty; use rustc_hir::Ty;
use rustc_middle::ty::Region; use rustc_middle::ty::Region;
@ -142,7 +142,7 @@ pub fn suggest_adding_lifetime_params<'tcx>(
sub: Region<'tcx>, sub: Region<'tcx>,
ty_sup: &'tcx Ty<'_>, ty_sup: &'tcx Ty<'_>,
ty_sub: &'tcx Ty<'_>, ty_sub: &'tcx Ty<'_>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
) { ) {
let suggestion = AddLifetimeParamsSuggestion { tcx, sub, ty_sup, ty_sub, add_note: false }; let suggestion = AddLifetimeParamsSuggestion { tcx, sub, ty_sup, ty_sub, add_note: false };
suggestion.add_to_diagnostic(err); suggestion.add_to_diagnostic(err);

View file

@ -9,7 +9,7 @@ use crate::infer::lexical_region_resolve::RegionResolutionError;
use crate::infer::{SubregionOrigin, TypeTrace}; use crate::infer::{SubregionOrigin, TypeTrace};
use crate::traits::{ObligationCauseCode, UnifyReceiverContext}; use crate::traits::{ObligationCauseCode, UnifyReceiverContext};
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{AddToDiagnostic, Applicability, Diagnostic, ErrorGuaranteed, MultiSpan}; use rustc_errors::{AddToDiagnostic, Applicability, DiagnosticBuilder, ErrorGuaranteed, MultiSpan};
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_hir::intravisit::{walk_ty, Visitor}; use rustc_hir::intravisit::{walk_ty, Visitor};
use rustc_hir::{ use rustc_hir::{
@ -261,7 +261,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
pub fn suggest_new_region_bound( pub fn suggest_new_region_bound(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
fn_returns: Vec<&rustc_hir::Ty<'_>>, fn_returns: Vec<&rustc_hir::Ty<'_>>,
lifetime_name: String, lifetime_name: String,
arg: Option<String>, arg: Option<String>,
@ -488,7 +488,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
/// `'static` obligation. Suggest relaxing that implicit bound. /// `'static` obligation. Suggest relaxing that implicit bound.
fn find_impl_on_dyn_trait( fn find_impl_on_dyn_trait(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
ty: Ty<'_>, ty: Ty<'_>,
ctxt: &UnifyReceiverContext<'tcx>, ctxt: &UnifyReceiverContext<'tcx>,
) -> bool { ) -> bool {
@ -521,7 +521,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
fn suggest_constrain_dyn_trait_in_impl( fn suggest_constrain_dyn_trait_in_impl(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
found_dids: &FxIndexSet<DefId>, found_dids: &FxIndexSet<DefId>,
ident: Ident, ident: Ident,
self_ty: &hir::Ty<'_>, self_ty: &hir::Ty<'_>,

View file

@ -5,7 +5,7 @@ use crate::errors::{
use crate::fluent_generated as fluent; use crate::fluent_generated as fluent;
use crate::infer::error_reporting::{note_and_explain_region, TypeErrCtxt}; use crate::infer::error_reporting::{note_and_explain_region, TypeErrCtxt};
use crate::infer::{self, SubregionOrigin}; use crate::infer::{self, SubregionOrigin};
use rustc_errors::{AddToDiagnostic, Diagnostic, DiagnosticBuilder}; use rustc_errors::{AddToDiagnostic, DiagnosticBuilder};
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::traits::ObligationCauseCode; use rustc_middle::traits::ObligationCauseCode;
use rustc_middle::ty::error::TypeError; use rustc_middle::ty::error::TypeError;
@ -15,7 +15,11 @@ use rustc_span::symbol::kw;
use super::ObligationCauseAsDiagArg; use super::ObligationCauseAsDiagArg;
impl<'tcx> TypeErrCtxt<'_, 'tcx> { impl<'tcx> TypeErrCtxt<'_, 'tcx> {
pub(super) fn note_region_origin(&self, err: &mut Diagnostic, origin: &SubregionOrigin<'tcx>) { pub(super) fn note_region_origin(
&self,
err: &mut DiagnosticBuilder<'_>,
origin: &SubregionOrigin<'tcx>,
) {
match *origin { match *origin {
infer::Subtype(ref trace) => RegionOriginNote::WithRequirement { infer::Subtype(ref trace) => RegionOriginNote::WithRequirement {
span: trace.cause.span, span: trace.cause.span,
@ -290,7 +294,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&self, &self,
trait_item_def_id: DefId, trait_item_def_id: DefId,
impl_item_def_id: LocalDefId, impl_item_def_id: LocalDefId,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
) { ) {
// FIXME(compiler-errors): Right now this is only being used for region // FIXME(compiler-errors): Right now this is only being used for region
// predicate mismatches. Ideally, we'd use it for *all* predicate mismatches, // predicate mismatches. Ideally, we'd use it for *all* predicate mismatches,

View file

@ -1,6 +1,6 @@
use super::TypeErrCtxt; use super::TypeErrCtxt;
use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect}; use rustc_errors::Applicability::{MachineApplicable, MaybeIncorrect};
use rustc_errors::{pluralize, Diagnostic, MultiSpan}; use rustc_errors::{pluralize, DiagnosticBuilder, MultiSpan};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_middle::traits::ObligationCauseCode; use rustc_middle::traits::ObligationCauseCode;
@ -15,7 +15,7 @@ use rustc_span::{def_id::DefId, sym, BytePos, Span, Symbol};
impl<'tcx> TypeErrCtxt<'_, 'tcx> { impl<'tcx> TypeErrCtxt<'_, 'tcx> {
pub fn note_and_explain_type_err( pub fn note_and_explain_type_err(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
err: TypeError<'tcx>, err: TypeError<'tcx>,
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
sp: Span, sp: Span,
@ -522,7 +522,7 @@ impl<T> Trait<T> for X {
fn suggest_constraint( fn suggest_constraint(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
msg: impl Fn() -> String, msg: impl Fn() -> String,
body_owner_def_id: DefId, body_owner_def_id: DefId,
proj_ty: &ty::AliasTy<'tcx>, proj_ty: &ty::AliasTy<'tcx>,
@ -595,7 +595,7 @@ impl<T> Trait<T> for X {
/// fn that returns the type. /// fn that returns the type.
fn expected_projection( fn expected_projection(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
proj_ty: &ty::AliasTy<'tcx>, proj_ty: &ty::AliasTy<'tcx>,
values: ExpectedFound<Ty<'tcx>>, values: ExpectedFound<Ty<'tcx>>,
body_owner_def_id: DefId, body_owner_def_id: DefId,
@ -705,7 +705,7 @@ fn foo(&self) -> Self::T { String::new() }
/// a return type. This can occur when dealing with `TryStream` (#71035). /// a return type. This can occur when dealing with `TryStream` (#71035).
fn suggest_constraining_opaque_associated_type( fn suggest_constraining_opaque_associated_type(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
msg: impl Fn() -> String, msg: impl Fn() -> String,
proj_ty: &ty::AliasTy<'tcx>, proj_ty: &ty::AliasTy<'tcx>,
ty: Ty<'tcx>, ty: Ty<'tcx>,
@ -740,7 +740,7 @@ fn foo(&self) -> Self::T { String::new() }
fn point_at_methods_that_satisfy_associated_type( fn point_at_methods_that_satisfy_associated_type(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
assoc_container_id: DefId, assoc_container_id: DefId,
current_method_ident: Option<Symbol>, current_method_ident: Option<Symbol>,
proj_ty_item_def_id: DefId, proj_ty_item_def_id: DefId,
@ -798,7 +798,7 @@ fn foo(&self) -> Self::T { String::new() }
fn point_at_associated_type( fn point_at_associated_type(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
body_owner_def_id: DefId, body_owner_def_id: DefId,
found: Ty<'tcx>, found: Ty<'tcx>,
) -> bool { ) -> bool {
@ -879,7 +879,7 @@ fn foo(&self) -> Self::T { String::new() }
/// type is defined on a supertrait of the one present in the bounds. /// type is defined on a supertrait of the one present in the bounds.
fn constrain_generic_bound_associated_type_structured_suggestion( fn constrain_generic_bound_associated_type_structured_suggestion(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
trait_ref: &ty::TraitRef<'tcx>, trait_ref: &ty::TraitRef<'tcx>,
bounds: hir::GenericBounds<'_>, bounds: hir::GenericBounds<'_>,
assoc: ty::AssocItem, assoc: ty::AssocItem,
@ -916,7 +916,7 @@ fn foo(&self) -> Self::T { String::new() }
/// associated type to a given type `ty`. /// associated type to a given type `ty`.
fn constrain_associated_type_structured_suggestion( fn constrain_associated_type_structured_suggestion(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
span: Span, span: Span,
assoc: ty::AssocItem, assoc: ty::AssocItem,
assoc_args: &[ty::GenericArg<'tcx>], assoc_args: &[ty::GenericArg<'tcx>],

View file

@ -1,7 +1,7 @@
use hir::def::CtorKind; use hir::def::CtorKind;
use hir::intravisit::{walk_expr, walk_stmt, Visitor}; use hir::intravisit::{walk_expr, walk_stmt, Visitor};
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{Applicability, Diagnostic}; use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_middle::traits::{ use rustc_middle::traits::{
IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode, IfExpressionCause, MatchExpressionArmCause, ObligationCause, ObligationCauseCode,
@ -76,7 +76,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
pub(super) fn suggest_boxing_for_return_impl_trait( pub(super) fn suggest_boxing_for_return_impl_trait(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
return_sp: Span, return_sp: Span,
arm_spans: impl Iterator<Item = Span>, arm_spans: impl Iterator<Item = Span>,
) { ) {
@ -100,7 +100,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&self, &self,
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
exp_found: &ty::error::ExpectedFound<Ty<'tcx>>, exp_found: &ty::error::ExpectedFound<Ty<'tcx>>,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
) { ) {
// Heavily inspired by `FnCtxt::suggest_compatible_variants`, with // Heavily inspired by `FnCtxt::suggest_compatible_variants`, with
// some modifications due to that being in typeck and this being in infer. // some modifications due to that being in typeck and this being in infer.
@ -177,7 +177,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
exp_span: Span, exp_span: Span,
exp_found: &ty::error::ExpectedFound<Ty<'tcx>>, exp_found: &ty::error::ExpectedFound<Ty<'tcx>>,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
) { ) {
debug!( debug!(
"suggest_await_on_expect_found: exp_span={:?}, expected_ty={:?}, found_ty={:?}", "suggest_await_on_expect_found: exp_span={:?}, expected_ty={:?}, found_ty={:?}",
@ -258,7 +258,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&self, &self,
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
exp_found: &ty::error::ExpectedFound<Ty<'tcx>>, exp_found: &ty::error::ExpectedFound<Ty<'tcx>>,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
) { ) {
debug!( debug!(
"suggest_accessing_field_where_appropriate(cause={:?}, exp_found={:?})", "suggest_accessing_field_where_appropriate(cause={:?}, exp_found={:?})",
@ -298,7 +298,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
span: Span, span: Span,
exp_found: &ty::error::ExpectedFound<Ty<'tcx>>, exp_found: &ty::error::ExpectedFound<Ty<'tcx>>,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
) { ) {
debug!("suggest_function_pointers(cause={:?}, exp_found={:?})", cause, exp_found); debug!("suggest_function_pointers(cause={:?}, exp_found={:?})", cause, exp_found);
let ty::error::ExpectedFound { expected, found } = exp_found; let ty::error::ExpectedFound { expected, found } = exp_found;
@ -532,7 +532,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
span: Span, span: Span,
hir: hir::Node<'_>, hir: hir::Node<'_>,
exp_found: &ty::error::ExpectedFound<ty::PolyTraitRef<'tcx>>, exp_found: &ty::error::ExpectedFound<ty::PolyTraitRef<'tcx>>,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
) { ) {
// 0. Extract fn_decl from hir // 0. Extract fn_decl from hir
let hir::Node::Expr(hir::Expr { let hir::Node::Expr(hir::Expr {
@ -818,7 +818,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&self, &self,
blk: &'tcx hir::Block<'tcx>, blk: &'tcx hir::Block<'tcx>,
expected_ty: Ty<'tcx>, expected_ty: Ty<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
) -> bool { ) -> bool {
let diag = self.consider_returning_binding_diag(blk, expected_ty); let diag = self.consider_returning_binding_diag(blk, expected_ty);
match diag { match diag {

View file

@ -1,3 +1,6 @@
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS; use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS;
use rustc_errors::{add_elided_lifetime_in_path_suggestion, DiagnosticBuilder}; use rustc_errors::{add_elided_lifetime_in_path_suggestion, DiagnosticBuilder};
use rustc_errors::{Applicability, SuggestionStyle}; use rustc_errors::{Applicability, SuggestionStyle};

View file

@ -1,5 +1,7 @@
use crate::fluent_generated as fluent; use crate::fluent_generated as fluent;
use rustc_errors::{codes::*, AddToDiagnostic, Diagnostic, SubdiagnosticMessageOp}; use rustc_errors::{
codes::*, AddToDiagnostic, DiagnosticBuilder, EmissionGuarantee, SubdiagnosticMessageOp,
};
use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_macros::{Diagnostic, Subdiagnostic};
use rustc_session::lint::Level; use rustc_session::lint::Level;
use rustc_span::{Span, Symbol}; use rustc_span::{Span, Symbol};
@ -24,7 +26,11 @@ pub enum OverruledAttributeSub {
} }
impl AddToDiagnostic for OverruledAttributeSub { impl AddToDiagnostic for OverruledAttributeSub {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_f: F,
) {
match self { match self {
OverruledAttributeSub::DefaultSource { id } => { OverruledAttributeSub::DefaultSource { id } => {
diag.note(fluent::lint_default_source); diag.note(fluent::lint_default_source);

View file

@ -1062,6 +1062,9 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
if self.lint_added_lints { if self.lint_added_lints {
let lint = builtin::UNKNOWN_LINTS; let lint = builtin::UNKNOWN_LINTS;
let (level, src) = self.lint_level(builtin::UNKNOWN_LINTS); let (level, src) = self.lint_level(builtin::UNKNOWN_LINTS);
// FIXME: make this translatable
#[allow(rustc::diagnostic_outside_of_impl)]
#[allow(rustc::untranslatable_diagnostic)]
lint_level( lint_level(
self.sess, self.sess,
lint, lint,

View file

@ -5,8 +5,8 @@ use std::num::NonZero;
use crate::errors::RequestedLevel; use crate::errors::RequestedLevel;
use crate::fluent_generated as fluent; use crate::fluent_generated as fluent;
use rustc_errors::{ use rustc_errors::{
codes::*, AddToDiagnostic, Applicability, DecorateLint, Diagnostic, DiagnosticBuilder, codes::*, AddToDiagnostic, Applicability, DecorateLint, DiagnosticBuilder, DiagnosticMessage,
DiagnosticMessage, DiagnosticStyledString, SubdiagnosticMessageOp, SuggestionStyle, DiagnosticStyledString, EmissionGuarantee, SubdiagnosticMessageOp, SuggestionStyle,
}; };
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_macros::{LintDiagnostic, Subdiagnostic}; use rustc_macros::{LintDiagnostic, Subdiagnostic};
@ -267,17 +267,21 @@ pub struct SuggestChangingAssocTypes<'a, 'b> {
pub ty: &'a rustc_hir::Ty<'b>, pub ty: &'a rustc_hir::Ty<'b>,
} }
impl AddToDiagnostic for SuggestChangingAssocTypes<'_, '_> { impl<'a, 'b> AddToDiagnostic for SuggestChangingAssocTypes<'a, 'b> {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_f: F,
) {
// Access to associates types should use `<T as Bound>::Assoc`, which does not need a // Access to associates types should use `<T as Bound>::Assoc`, which does not need a
// bound. Let's see if this type does that. // bound. Let's see if this type does that.
// We use a HIR visitor to walk the type. // We use a HIR visitor to walk the type.
use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::intravisit::{self, Visitor};
struct WalkAssocTypes<'a> { struct WalkAssocTypes<'a, 'b, G: EmissionGuarantee> {
err: &'a mut Diagnostic, err: &'a mut DiagnosticBuilder<'b, G>,
} }
impl Visitor<'_> for WalkAssocTypes<'_> { impl<'a, 'b, G: EmissionGuarantee> Visitor<'_> for WalkAssocTypes<'a, 'b, G> {
fn visit_qpath( fn visit_qpath(
&mut self, &mut self,
qpath: &rustc_hir::QPath<'_>, qpath: &rustc_hir::QPath<'_>,
@ -320,7 +324,11 @@ pub struct BuiltinTypeAliasGenericBoundsSuggestion {
} }
impl AddToDiagnostic for BuiltinTypeAliasGenericBoundsSuggestion { impl AddToDiagnostic for BuiltinTypeAliasGenericBoundsSuggestion {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_f: F,
) {
diag.multipart_suggestion( diag.multipart_suggestion(
fluent::lint_suggestion, fluent::lint_suggestion,
self.suggestions, self.suggestions,
@ -437,7 +445,11 @@ pub struct BuiltinUnpermittedTypeInitSub {
} }
impl AddToDiagnostic for BuiltinUnpermittedTypeInitSub { impl AddToDiagnostic for BuiltinUnpermittedTypeInitSub {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_f: F,
) {
let mut err = self.err; let mut err = self.err;
loop { loop {
if let Some(span) = err.span { if let Some(span) = err.span {
@ -488,7 +500,11 @@ pub struct BuiltinClashingExternSub<'a> {
} }
impl AddToDiagnostic for BuiltinClashingExternSub<'_> { impl AddToDiagnostic for BuiltinClashingExternSub<'_> {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_f: F,
) {
let mut expected_str = DiagnosticStyledString::new(); let mut expected_str = DiagnosticStyledString::new();
expected_str.push(self.expected.fn_sig(self.tcx).to_string(), false); expected_str.push(self.expected.fn_sig(self.tcx).to_string(), false);
let mut found_str = DiagnosticStyledString::new(); let mut found_str = DiagnosticStyledString::new();
@ -766,7 +782,11 @@ pub struct HiddenUnicodeCodepointsDiagLabels {
} }
impl AddToDiagnostic for HiddenUnicodeCodepointsDiagLabels { impl AddToDiagnostic for HiddenUnicodeCodepointsDiagLabels {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_f: F,
) {
for (c, span) in self.spans { for (c, span) in self.spans {
diag.span_label(span, format!("{c:?}")); diag.span_label(span, format!("{c:?}"));
} }
@ -780,7 +800,11 @@ pub enum HiddenUnicodeCodepointsDiagSub {
// Used because of multiple multipart_suggestion and note // Used because of multiple multipart_suggestion and note
impl AddToDiagnostic for HiddenUnicodeCodepointsDiagSub { impl AddToDiagnostic for HiddenUnicodeCodepointsDiagSub {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_f: F,
) {
match self { match self {
HiddenUnicodeCodepointsDiagSub::Escape { spans } => { HiddenUnicodeCodepointsDiagSub::Escape { spans } => {
diag.multipart_suggestion_with_style( diag.multipart_suggestion_with_style(
@ -928,7 +952,11 @@ pub struct NonBindingLetSub {
} }
impl AddToDiagnostic for NonBindingLetSub { impl AddToDiagnostic for NonBindingLetSub {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_f: F,
) {
let can_suggest_binding = self.drop_fn_start_end.is_some() || !self.is_assign_desugar; let can_suggest_binding = self.drop_fn_start_end.is_some() || !self.is_assign_desugar;
if can_suggest_binding { if can_suggest_binding {
@ -1208,7 +1236,11 @@ pub enum NonSnakeCaseDiagSub {
} }
impl AddToDiagnostic for NonSnakeCaseDiagSub { impl AddToDiagnostic for NonSnakeCaseDiagSub {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_f: F,
) {
match self { match self {
NonSnakeCaseDiagSub::Label { span } => { NonSnakeCaseDiagSub::Label { span } => {
diag.span_label(span, fluent::lint_label); diag.span_label(span, fluent::lint_label);
@ -1401,7 +1433,11 @@ pub enum OverflowingBinHexSign {
} }
impl AddToDiagnostic for OverflowingBinHexSign { impl AddToDiagnostic for OverflowingBinHexSign {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_f: F,
) {
match self { match self {
OverflowingBinHexSign::Positive => { OverflowingBinHexSign::Positive => {
diag.note(fluent::lint_positive_note); diag.note(fluent::lint_positive_note);

View file

@ -87,9 +87,13 @@ impl SubdiagnosticDeriveBuilder {
let f = &self.f; let f = &self.f;
let ret = structure.gen_impl(quote! { let ret = structure.gen_impl(quote! {
gen impl rustc_errors::AddToDiagnostic for @Self { gen impl rustc_errors::AddToDiagnostic for @Self {
fn add_to_diagnostic_with<__F>(self, #diag: &mut rustc_errors::Diagnostic, #f: __F) fn add_to_diagnostic_with<__G, __F>(
where self,
__F: rustc_errors::SubdiagnosticMessageOp, #diag: &mut rustc_errors::DiagnosticBuilder<'_, __G>,
#f: __F
) where
__G: rustc_errors::EmissionGuarantee,
__F: rustc_errors::SubdiagnosticMessageOp<__G>,
{ {
#implementation #implementation
} }

View file

@ -505,6 +505,8 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for MultipleCandidates {
diag.code(E0464); diag.code(E0464);
diag.span(self.span); diag.span(self.span);
for (i, candidate) in self.candidates.iter().enumerate() { for (i, candidate) in self.candidates.iter().enumerate() {
// FIXME: make this translatable
#[allow(rustc::untranslatable_diagnostic)]
diag.note(format!("candidate #{}: {}", i + 1, candidate.display())); diag.note(format!("candidate #{}: {}", i + 1, candidate.display()));
} }
diag diag
@ -601,6 +603,8 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for InvalidMetadataFiles {
diag.code(E0786); diag.code(E0786);
diag.span(self.span); diag.span(self.span);
for crate_rejection in self.crate_rejections { for crate_rejection in self.crate_rejections {
// FIXME: make this translatable
#[allow(rustc::untranslatable_diagnostic)]
diag.note(crate_rejection); diag.note(crate_rejection);
} }
diag diag

View file

@ -2,7 +2,7 @@ use std::cmp;
use rustc_data_structures::fx::FxIndexMap; use rustc_data_structures::fx::FxIndexMap;
use rustc_data_structures::sorted_map::SortedMap; use rustc_data_structures::sorted_map::SortedMap;
use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticMessage, MultiSpan}; use rustc_errors::{DiagnosticBuilder, DiagnosticMessage, MultiSpan};
use rustc_hir::{HirId, ItemLocalId}; use rustc_hir::{HirId, ItemLocalId};
use rustc_session::lint::{ use rustc_session::lint::{
builtin::{self, FORBIDDEN_LINT_GROUPS}, builtin::{self, FORBIDDEN_LINT_GROUPS},
@ -204,7 +204,7 @@ pub fn explain_lint_level_source(
lint: &'static Lint, lint: &'static Lint,
level: Level, level: Level,
src: LintLevelSource, src: LintLevelSource,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_, ()>,
) { ) {
let name = lint.name_lower(); let name = lint.name_lower();
if let Level::Allow = level { if let Level::Allow = level {
@ -359,7 +359,7 @@ pub fn lint_level(
// Lint diagnostics that are covered by the expect level will not be emitted outside // Lint diagnostics that are covered by the expect level will not be emitted outside
// the compiler. It is therefore not necessary to add any information for the user. // the compiler. It is therefore not necessary to add any information for the user.
// This will therefore directly call the decorate function which will in turn emit // This will therefore directly call the decorate function which will in turn emit
// the `Diagnostic`. // the diagnostic.
if let Level::Expect(_) = level { if let Level::Expect(_) = level {
decorate(&mut err); decorate(&mut err);
err.emit(); err.emit();
@ -401,7 +401,7 @@ pub fn lint_level(
// Finally, run `decorate`. // Finally, run `decorate`.
decorate(&mut err); decorate(&mut err);
explain_lint_level_source(lint, level, src, &mut *err); explain_lint_level_source(lint, level, src, &mut err);
err.emit() err.emit()
} }
lint_level_impl(sess, lint, level, src, span, msg, Box::new(decorate)) lint_level_impl(sess, lint, level, src, span, msg, Box::new(decorate))

View file

@ -9,7 +9,7 @@ use rustc_attr::{
self as attr, ConstStability, DefaultBodyStability, DeprecatedSince, Deprecation, Stability, self as attr, ConstStability, DefaultBodyStability, DeprecatedSince, Deprecation, Stability,
}; };
use rustc_data_structures::unord::UnordMap; use rustc_data_structures::unord::UnordMap;
use rustc_errors::{Applicability, Diagnostic}; use rustc_errors::{Applicability, DiagnosticBuilder};
use rustc_feature::GateIssue; use rustc_feature::GateIssue;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap}; use rustc_hir::def_id::{DefId, LocalDefId, LocalDefIdMap};
@ -125,7 +125,7 @@ pub fn report_unstable(
} }
pub fn deprecation_suggestion( pub fn deprecation_suggestion(
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_, ()>,
kind: &str, kind: &str,
suggestion: Option<Symbol>, suggestion: Option<Symbol>,
span: Span, span: Span,

View file

@ -16,7 +16,7 @@ use crate::ty::GenericArgsRef;
use crate::ty::{self, AdtKind, Ty}; use crate::ty::{self, AdtKind, Ty};
use rustc_data_structures::sync::Lrc; use rustc_data_structures::sync::Lrc;
use rustc_errors::{Applicability, Diagnostic}; use rustc_errors::{Applicability, DiagnosticBuilder, EmissionGuarantee};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_span::def_id::{LocalDefId, CRATE_DEF_ID}; use rustc_span::def_id::{LocalDefId, CRATE_DEF_ID};
@ -908,7 +908,7 @@ pub enum ObjectSafetyViolationSolution {
} }
impl ObjectSafetyViolationSolution { impl ObjectSafetyViolationSolution {
pub fn add_to(self, err: &mut Diagnostic) { pub fn add_to<G: EmissionGuarantee>(self, err: &mut DiagnosticBuilder<'_, G>) {
match self { match self {
ObjectSafetyViolationSolution::None => {} ObjectSafetyViolationSolution::None => {}
ObjectSafetyViolationSolution::AddSelfOrMakeSized { ObjectSafetyViolationSolution::AddSelfOrMakeSized {

View file

@ -11,7 +11,7 @@ use crate::ty::{
}; };
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_errors::{Applicability, Diagnostic, DiagnosticArgValue, IntoDiagnosticArg}; use rustc_errors::{Applicability, DiagnosticArgValue, DiagnosticBuilder, IntoDiagnosticArg};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
@ -111,7 +111,7 @@ where
pub fn suggest_arbitrary_trait_bound<'tcx>( pub fn suggest_arbitrary_trait_bound<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
generics: &hir::Generics<'_>, generics: &hir::Generics<'_>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
trait_pred: PolyTraitPredicate<'tcx>, trait_pred: PolyTraitPredicate<'tcx>,
associated_ty: Option<(&'static str, Ty<'tcx>)>, associated_ty: Option<(&'static str, Ty<'tcx>)>,
) -> bool { ) -> bool {
@ -216,7 +216,7 @@ fn suggest_changing_unsized_bound(
pub fn suggest_constraining_type_param( pub fn suggest_constraining_type_param(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
generics: &hir::Generics<'_>, generics: &hir::Generics<'_>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
param_name: &str, param_name: &str,
constraint: &str, constraint: &str,
def_id: Option<DefId>, def_id: Option<DefId>,
@ -235,7 +235,7 @@ pub fn suggest_constraining_type_param(
pub fn suggest_constraining_type_params<'a>( pub fn suggest_constraining_type_params<'a>(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
generics: &hir::Generics<'_>, generics: &hir::Generics<'_>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
param_names_and_constraints: impl Iterator<Item = (&'a str, &'a str, Option<DefId>)>, param_names_and_constraints: impl Iterator<Item = (&'a str, &'a str, Option<DefId>)>,
span_to_replace: Option<Span>, span_to_replace: Option<Span>,
) -> bool { ) -> bool {

View file

@ -1,7 +1,7 @@
use crate::fluent_generated as fluent; use crate::fluent_generated as fluent;
use rustc_errors::DiagnosticArgValue; use rustc_errors::DiagnosticArgValue;
use rustc_errors::{ use rustc_errors::{
codes::*, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, codes::*, AddToDiagnostic, Applicability, DiagCtxt, DiagnosticBuilder, EmissionGuarantee,
IntoDiagnostic, Level, MultiSpan, SubdiagnosticMessageOp, IntoDiagnostic, Level, MultiSpan, SubdiagnosticMessageOp,
}; };
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
@ -420,7 +420,11 @@ pub struct UnsafeNotInheritedLintNote {
} }
impl AddToDiagnostic for UnsafeNotInheritedLintNote { impl AddToDiagnostic for UnsafeNotInheritedLintNote {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_f: F,
) {
diag.span_note(self.signature_span, fluent::mir_build_unsafe_fn_safe_body); diag.span_note(self.signature_span, fluent::mir_build_unsafe_fn_safe_body);
let body_start = self.body_span.shrink_to_lo(); let body_start = self.body_span.shrink_to_lo();
let body_end = self.body_span.shrink_to_hi(); let body_end = self.body_span.shrink_to_hi();
@ -863,7 +867,11 @@ pub struct Variant {
} }
impl<'tcx> AddToDiagnostic for AdtDefinedHere<'tcx> { impl<'tcx> AddToDiagnostic for AdtDefinedHere<'tcx> {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_f: F,
) {
diag.arg("ty", self.ty); diag.arg("ty", self.ty);
let mut spans = MultiSpan::from(self.adt_def_span); let mut spans = MultiSpan::from(self.adt_def_span);

View file

@ -87,6 +87,9 @@ pub(crate) struct RequiresUnsafeDetail {
} }
impl RequiresUnsafeDetail { impl RequiresUnsafeDetail {
// FIXME: make this translatable
#[allow(rustc::diagnostic_outside_of_impl)]
#[allow(rustc::untranslatable_diagnostic)]
fn add_subdiagnostics<G: EmissionGuarantee>(&self, diag: &mut DiagnosticBuilder<'_, G>) { fn add_subdiagnostics<G: EmissionGuarantee>(&self, diag: &mut DiagnosticBuilder<'_, G>) {
use UnsafetyViolationDetails::*; use UnsafetyViolationDetails::*;
match self.violation { match self.violation {

View file

@ -56,6 +56,7 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for UnusedGenericParamsHint {
// FIXME: I can figure out how to do a label with a fluent string with a fixed message, // FIXME: I can figure out how to do a label with a fluent string with a fixed message,
// or a label with a dynamic value in a hard-coded string, but I haven't figured out // or a label with a dynamic value in a hard-coded string, but I haven't figured out
// how to combine the two. 😢 // how to combine the two. 😢
#[allow(rustc::untranslatable_diagnostic)]
diag.span_label(span, format!("generic parameter `{name}` is unused")); diag.span_label(span, format!("generic parameter `{name}` is unused"));
} }
diag diag

View file

@ -3,7 +3,7 @@ use std::borrow::Cow;
use rustc_ast::token::Token; use rustc_ast::token::Token;
use rustc_ast::{Path, Visibility}; use rustc_ast::{Path, Visibility};
use rustc_errors::{ use rustc_errors::{
codes::*, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, codes::*, AddToDiagnostic, Applicability, DiagCtxt, DiagnosticBuilder, EmissionGuarantee,
IntoDiagnostic, Level, SubdiagnosticMessageOp, IntoDiagnostic, Level, SubdiagnosticMessageOp,
}; };
use rustc_macros::{Diagnostic, Subdiagnostic}; use rustc_macros::{Diagnostic, Subdiagnostic};
@ -1475,7 +1475,11 @@ pub(crate) struct FnTraitMissingParen {
} }
impl AddToDiagnostic for FnTraitMissingParen { impl AddToDiagnostic for FnTraitMissingParen {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_: F,
) {
diag.span_label(self.span, crate::fluent_generated::parse_fn_trait_missing_paren); diag.span_label(self.span, crate::fluent_generated::parse_fn_trait_missing_paren);
let applicability = if self.machine_applicable { let applicability = if self.machine_applicable {
Applicability::MachineApplicable Applicability::MachineApplicable

View file

@ -1,6 +1,6 @@
use super::UnmatchedDelim; use super::UnmatchedDelim;
use rustc_ast::token::Delimiter; use rustc_ast::token::Delimiter;
use rustc_errors::Diagnostic; use rustc_errors::DiagnosticBuilder;
use rustc_span::source_map::SourceMap; use rustc_span::source_map::SourceMap;
use rustc_span::Span; use rustc_span::Span;
@ -31,7 +31,7 @@ pub fn same_indentation_level(sm: &SourceMap, open_sp: Span, close_sp: Span) ->
// When we get a `)` or `]` for `{`, we should emit help message here // When we get a `)` or `]` for `{`, we should emit help message here
// it's more friendly compared to report `unmatched error` in later phase // it's more friendly compared to report `unmatched error` in later phase
pub fn report_missing_open_delim( pub fn report_missing_open_delim(
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
unmatched_delims: &[UnmatchedDelim], unmatched_delims: &[UnmatchedDelim],
) -> bool { ) -> bool {
let mut reported_missing_open = false; let mut reported_missing_open = false;
@ -55,7 +55,7 @@ pub fn report_missing_open_delim(
} }
pub fn report_suspicious_mismatch_block( pub fn report_suspicious_mismatch_block(
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
diag_info: &TokenTreeDiagInfo, diag_info: &TokenTreeDiagInfo,
sm: &SourceMap, sm: &SourceMap,
delim: Delimiter, delim: Delimiter,

View file

@ -8,7 +8,7 @@ use super::{AttrWrapper, Capturing, FnParseMode, ForceCollect, Parser, PathStyle
use rustc_ast as ast; use rustc_ast as ast;
use rustc_ast::attr; use rustc_ast::attr;
use rustc_ast::token::{self, Delimiter, Nonterminal}; use rustc_ast::token::{self, Delimiter, Nonterminal};
use rustc_errors::{codes::*, Diagnostic, PResult}; use rustc_errors::{codes::*, DiagnosticBuilder, PResult};
use rustc_span::{sym, BytePos, Span}; use rustc_span::{sym, BytePos, Span};
use thin_vec::ThinVec; use thin_vec::ThinVec;
use tracing::debug; use tracing::debug;
@ -141,7 +141,7 @@ impl<'a> Parser<'a> {
fn annotate_following_item_if_applicable( fn annotate_following_item_if_applicable(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
span: Span, span: Span,
attr_type: OuterAttributeType, attr_type: OuterAttributeType,
) -> Option<Span> { ) -> Option<Span> {

View file

@ -34,8 +34,8 @@ use rustc_ast::{
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{ use rustc_errors::{
pluralize, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, pluralize, AddToDiagnostic, Applicability, DiagCtxt, DiagnosticBuilder, ErrorGuaranteed,
ErrorGuaranteed, FatalError, PErr, PResult, FatalError, PErr, PResult,
}; };
use rustc_session::errors::ExprParenthesesNeeded; use rustc_session::errors::ExprParenthesesNeeded;
use rustc_span::source_map::Spanned; use rustc_span::source_map::Spanned;
@ -208,11 +208,11 @@ struct MultiSugg {
} }
impl MultiSugg { impl MultiSugg {
fn emit(self, err: &mut Diagnostic) { fn emit(self, err: &mut DiagnosticBuilder<'_>) {
err.multipart_suggestion(self.msg, self.patches, self.applicability); err.multipart_suggestion(self.msg, self.patches, self.applicability);
} }
fn emit_verbose(self, err: &mut Diagnostic) { fn emit_verbose(self, err: &mut DiagnosticBuilder<'_>) {
err.multipart_suggestion_verbose(self.msg, self.patches, self.applicability); err.multipart_suggestion_verbose(self.msg, self.patches, self.applicability);
} }
} }
@ -846,7 +846,7 @@ impl<'a> Parser<'a> {
err.emit(); err.emit();
} }
fn check_too_many_raw_str_terminators(&mut self, err: &mut Diagnostic) -> bool { fn check_too_many_raw_str_terminators(&mut self, err: &mut DiagnosticBuilder<'_>) -> bool {
let sm = self.sess.source_map(); let sm = self.sess.source_map();
match (&self.prev_token.kind, &self.token.kind) { match (&self.prev_token.kind, &self.token.kind) {
( (
@ -2179,7 +2179,7 @@ impl<'a> Parser<'a> {
pub(super) fn parameter_without_type( pub(super) fn parameter_without_type(
&mut self, &mut self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
pat: P<ast::Pat>, pat: P<ast::Pat>,
require_name: bool, require_name: bool,
first_param: bool, first_param: bool,

View file

@ -25,9 +25,7 @@ use rustc_ast::{Arm, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLim
use rustc_ast::{ClosureBinder, MetaItemLit, StmtKind}; use rustc_ast::{ClosureBinder, MetaItemLit, StmtKind};
use rustc_ast_pretty::pprust; use rustc_ast_pretty::pprust;
use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{ use rustc_errors::{AddToDiagnostic, Applicability, DiagnosticBuilder, PResult, StashKey};
AddToDiagnostic, Applicability, Diagnostic, DiagnosticBuilder, PResult, StashKey,
};
use rustc_lexer::unescape::unescape_char; use rustc_lexer::unescape::unescape_char;
use rustc_macros::Subdiagnostic; use rustc_macros::Subdiagnostic;
use rustc_session::errors::{report_lit_error, ExprParenthesesNeeded}; use rustc_session::errors::{report_lit_error, ExprParenthesesNeeded};
@ -865,7 +863,7 @@ impl<'a> Parser<'a> {
); );
let mut err = self.dcx().struct_span_err(span, msg); let mut err = self.dcx().struct_span_err(span, msg);
let suggest_parens = |err: &mut Diagnostic| { let suggest_parens = |err: &mut DiagnosticBuilder<'_>| {
let suggestions = vec![ let suggestions = vec![
(span.shrink_to_lo(), "(".to_string()), (span.shrink_to_lo(), "(".to_string()),
(span.shrink_to_hi(), ")".to_string()), (span.shrink_to_hi(), ")".to_string()),
@ -3437,7 +3435,7 @@ impl<'a> Parser<'a> {
let mut recover_async = false; let mut recover_async = false;
let in_if_guard = self.restrictions.contains(Restrictions::IN_IF_GUARD); let in_if_guard = self.restrictions.contains(Restrictions::IN_IF_GUARD);
let mut async_block_err = |e: &mut Diagnostic, span: Span| { let mut async_block_err = |e: &mut DiagnosticBuilder<'_>, span: Span| {
recover_async = true; recover_async = true;
errors::AsyncBlockIn2015 { span }.add_to_diagnostic(e); errors::AsyncBlockIn2015 { span }.add_to_diagnostic(e);
errors::HelpUseLatestEdition::new().add_to_diagnostic(e); errors::HelpUseLatestEdition::new().add_to_diagnostic(e);

View file

@ -156,9 +156,12 @@ impl<'tcx> CheckConstVisitor<'tcx> {
// is a pretty narrow case, however. // is a pretty narrow case, however.
if tcx.sess.is_nightly_build() { if tcx.sess.is_nightly_build() {
for gate in missing_secondary { for gate in missing_secondary {
let note = // FIXME: make this translatable
format!("add `#![feature({gate})]` to the crate attributes to enable",); #[allow(rustc::diagnostic_outside_of_impl)]
err.help(note); #[allow(rustc::untranslatable_diagnostic)]
err.help(format!(
"add `#![feature({gate})]` to the crate attributes to enable"
));
} }
} }

View file

@ -6,9 +6,8 @@ use std::{
use crate::fluent_generated as fluent; use crate::fluent_generated as fluent;
use rustc_ast::Label; use rustc_ast::Label;
use rustc_errors::{ use rustc_errors::{
codes::*, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, codes::*, AddToDiagnostic, Applicability, DiagCtxt, DiagnosticBuilder, DiagnosticSymbolList,
DiagnosticSymbolList, EmissionGuarantee, IntoDiagnostic, Level, MultiSpan, EmissionGuarantee, IntoDiagnostic, Level, MultiSpan, SubdiagnosticMessageOp,
SubdiagnosticMessageOp,
}; };
use rustc_hir::{self as hir, ExprKind, Target}; use rustc_hir::{self as hir, ExprKind, Target};
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic}; use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
@ -1754,7 +1753,11 @@ pub struct UnusedVariableStringInterp {
} }
impl AddToDiagnostic for UnusedVariableStringInterp { impl AddToDiagnostic for UnusedVariableStringInterp {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_f: F,
) {
diag.span_label(self.lit, crate::fluent_generated::passes_maybe_string_interpolation); diag.span_label(self.lit, crate::fluent_generated::passes_maybe_string_interpolation);
diag.multipart_suggestion( diag.multipart_suggestion(
crate::fluent_generated::passes_string_interpolation_only_works, crate::fluent_generated::passes_string_interpolation_only_works,

View file

@ -1,4 +1,4 @@
use rustc_errors::{AddToDiagnostic, Diagnostic, SubdiagnosticMessageOp}; use rustc_errors::{AddToDiagnostic, DiagnosticBuilder, EmissionGuarantee, SubdiagnosticMessageOp};
use rustc_macros::{LintDiagnostic, Subdiagnostic}; use rustc_macros::{LintDiagnostic, Subdiagnostic};
use rustc_middle::thir::Pat; use rustc_middle::thir::Pat;
use rustc_middle::ty::Ty; use rustc_middle::ty::Ty;
@ -62,7 +62,11 @@ pub struct Overlap<'tcx> {
} }
impl<'tcx> AddToDiagnostic for Overlap<'tcx> { impl<'tcx> AddToDiagnostic for Overlap<'tcx> {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_: F,
) {
let Overlap { span, range } = self; let Overlap { span, range } = self;
// FIXME(mejrs) unfortunately `#[derive(LintDiagnostic)]` // FIXME(mejrs) unfortunately `#[derive(LintDiagnostic)]`

View file

@ -7,7 +7,7 @@ use rustc_ast_pretty::pprust;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{ use rustc_errors::{
codes::*, pluralize, report_ambiguity_error, struct_span_code_err, Applicability, DiagCtxt, codes::*, pluralize, report_ambiguity_error, struct_span_code_err, Applicability, DiagCtxt,
Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, SuggestionStyle, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, SuggestionStyle,
}; };
use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_feature::BUILTIN_ATTRIBUTES;
use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::Namespace::{self, *};
@ -360,7 +360,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
/// ``` /// ```
fn add_suggestion_for_rename_of_use( fn add_suggestion_for_rename_of_use(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
name: Symbol, name: Symbol,
import: Import<'_>, import: Import<'_>,
binding_span: Span, binding_span: Span,
@ -436,7 +436,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
/// as characters expected by span manipulations won't be present. /// as characters expected by span manipulations won't be present.
fn add_suggestion_for_duplicate_nested_use( fn add_suggestion_for_duplicate_nested_use(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
import: Import<'_>, import: Import<'_>,
binding_span: Span, binding_span: Span,
) { ) {
@ -1399,7 +1399,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
pub(crate) fn unresolved_macro_suggestions( pub(crate) fn unresolved_macro_suggestions(
&mut self, &mut self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
macro_kind: MacroKind, macro_kind: MacroKind,
parent_scope: &ParentScope<'a>, parent_scope: &ParentScope<'a>,
ident: Ident, ident: Ident,
@ -1515,7 +1515,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
pub(crate) fn add_typo_suggestion( pub(crate) fn add_typo_suggestion(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
suggestion: Option<TypoSuggestion>, suggestion: Option<TypoSuggestion>,
span: Span, span: Span,
) -> bool { ) -> bool {
@ -2461,7 +2461,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
/// Finds a cfg-ed out item inside `module` with the matching name. /// Finds a cfg-ed out item inside `module` with the matching name.
pub(crate) fn find_cfg_stripped( pub(crate) fn find_cfg_stripped(
&mut self, &mut self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
segment: &Symbol, segment: &Symbol,
module: DefId, module: DefId,
) { ) {
@ -2670,7 +2670,7 @@ pub(crate) enum DiagnosticMode {
pub(crate) fn import_candidates( pub(crate) fn import_candidates(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
// This is `None` if all placement locations are inside expansions // This is `None` if all placement locations are inside expansions
use_placement_span: Option<Span>, use_placement_span: Option<Span>,
candidates: &[ImportSuggestion], candidates: &[ImportSuggestion],
@ -2696,7 +2696,7 @@ pub(crate) fn import_candidates(
/// found and suggested, returns `true`, otherwise returns `false`. /// found and suggested, returns `true`, otherwise returns `false`.
fn show_candidates( fn show_candidates(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
// This is `None` if all placement locations are inside expansions // This is `None` if all placement locations are inside expansions
use_placement_span: Option<Span>, use_placement_span: Option<Span>,
candidates: &[ImportSuggestion], candidates: &[ImportSuggestion],

View file

@ -1,3 +1,5 @@
// ignore-tidy-filelength
use crate::diagnostics::{ImportSuggestion, LabelSuggestion, TypoSuggestion}; use crate::diagnostics::{ImportSuggestion, LabelSuggestion, TypoSuggestion};
use crate::late::{AliasPossibility, LateResolutionVisitor, RibKind}; use crate::late::{AliasPossibility, LateResolutionVisitor, RibKind};
use crate::late::{LifetimeBinderKind, LifetimeRes, LifetimeRibKind, LifetimeUseSet}; use crate::late::{LifetimeBinderKind, LifetimeRes, LifetimeRibKind, LifetimeUseSet};
@ -16,8 +18,8 @@ use rustc_ast::{
use rustc_ast_pretty::pprust::where_bound_predicate_to_string; use rustc_ast_pretty::pprust::where_bound_predicate_to_string;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{ use rustc_errors::{
codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, codes::*, pluralize, struct_span_code_err, Applicability, DiagnosticBuilder, ErrorGuaranteed,
ErrorGuaranteed, MultiSpan, SuggestionStyle, MultiSpan, SuggestionStyle,
}; };
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{self, CtorKind, CtorOf, DefKind}; use rustc_hir::def::{self, CtorKind, CtorOf, DefKind};
@ -496,7 +498,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
fn detect_assoc_type_constraint_meant_as_path( fn detect_assoc_type_constraint_meant_as_path(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
base_error: &BaseError, base_error: &BaseError,
) { ) {
let Some(ty) = self.diagnostic_metadata.current_type_path else { let Some(ty) = self.diagnostic_metadata.current_type_path else {
@ -537,7 +539,12 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
} }
} }
fn suggest_self_or_self_ref(&mut self, err: &mut Diagnostic, path: &[Segment], span: Span) { fn suggest_self_or_self_ref(
&mut self,
err: &mut DiagnosticBuilder<'_>,
path: &[Segment],
span: Span,
) {
if !self.self_type_is_available() { if !self.self_type_is_available() {
return; return;
} }
@ -582,7 +589,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
fn try_lookup_name_relaxed( fn try_lookup_name_relaxed(
&mut self, &mut self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
source: PathSource<'_>, source: PathSource<'_>,
path: &[Segment], path: &[Segment],
following_seg: Option<&Segment>, following_seg: Option<&Segment>,
@ -786,7 +793,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
fn suggest_trait_and_bounds( fn suggest_trait_and_bounds(
&mut self, &mut self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
source: PathSource<'_>, source: PathSource<'_>,
res: Option<Res>, res: Option<Res>,
span: Span, span: Span,
@ -863,7 +870,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
fn suggest_typo( fn suggest_typo(
&mut self, &mut self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
source: PathSource<'_>, source: PathSource<'_>,
path: &[Segment], path: &[Segment],
following_seg: Option<&Segment>, following_seg: Option<&Segment>,
@ -903,7 +910,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
fn suggest_shadowed( fn suggest_shadowed(
&mut self, &mut self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
source: PathSource<'_>, source: PathSource<'_>,
path: &[Segment], path: &[Segment],
following_seg: Option<&Segment>, following_seg: Option<&Segment>,
@ -936,7 +943,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
fn err_code_special_cases( fn err_code_special_cases(
&mut self, &mut self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
source: PathSource<'_>, source: PathSource<'_>,
path: &[Segment], path: &[Segment],
span: Span, span: Span,
@ -981,7 +988,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
/// Emit special messages for unresolved `Self` and `self`. /// Emit special messages for unresolved `Self` and `self`.
fn suggest_self_ty( fn suggest_self_ty(
&mut self, &mut self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
source: PathSource<'_>, source: PathSource<'_>,
path: &[Segment], path: &[Segment],
span: Span, span: Span,
@ -1008,7 +1015,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
fn suggest_self_value( fn suggest_self_value(
&mut self, &mut self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
source: PathSource<'_>, source: PathSource<'_>,
path: &[Segment], path: &[Segment],
span: Span, span: Span,
@ -1090,7 +1097,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
fn suggest_at_operator_in_slice_pat_with_range( fn suggest_at_operator_in_slice_pat_with_range(
&mut self, &mut self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
path: &[Segment], path: &[Segment],
) { ) {
let Some(pat) = self.diagnostic_metadata.current_pat else { return }; let Some(pat) = self.diagnostic_metadata.current_pat else { return };
@ -1129,7 +1136,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
fn suggest_swapping_misplaced_self_ty_and_trait( fn suggest_swapping_misplaced_self_ty_and_trait(
&mut self, &mut self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
source: PathSource<'_>, source: PathSource<'_>,
res: Option<Res>, res: Option<Res>,
span: Span, span: Span,
@ -1155,7 +1162,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
} }
} }
fn suggest_bare_struct_literal(&mut self, err: &mut Diagnostic) { fn suggest_bare_struct_literal(&mut self, err: &mut DiagnosticBuilder<'_>) {
if let Some(span) = self.diagnostic_metadata.current_block_could_be_bare_struct_literal { if let Some(span) = self.diagnostic_metadata.current_block_could_be_bare_struct_literal {
err.multipart_suggestion( err.multipart_suggestion(
"you might have meant to write a `struct` literal", "you might have meant to write a `struct` literal",
@ -1170,7 +1177,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
fn suggest_changing_type_to_const_param( fn suggest_changing_type_to_const_param(
&mut self, &mut self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
res: Option<Res>, res: Option<Res>,
source: PathSource<'_>, source: PathSource<'_>,
span: Span, span: Span,
@ -1222,7 +1229,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
fn suggest_pattern_match_with_let( fn suggest_pattern_match_with_let(
&mut self, &mut self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
source: PathSource<'_>, source: PathSource<'_>,
span: Span, span: Span,
) -> bool { ) -> bool {
@ -1277,7 +1284,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
} }
/// Given `where <T as Bar>::Baz: String`, suggest `where T: Bar<Baz = String>`. /// Given `where <T as Bar>::Baz: String`, suggest `where T: Bar<Baz = String>`.
fn restrict_assoc_type_in_where_clause(&mut self, span: Span, err: &mut Diagnostic) -> bool { fn restrict_assoc_type_in_where_clause(
&mut self,
span: Span,
err: &mut DiagnosticBuilder<'_>,
) -> bool {
// Detect that we are actually in a `where` predicate. // Detect that we are actually in a `where` predicate.
let (bounded_ty, bounds, where_span) = let (bounded_ty, bounds, where_span) =
if let Some(ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate { if let Some(ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
@ -1410,7 +1421,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
/// Returns `true` if able to provide context-dependent help. /// Returns `true` if able to provide context-dependent help.
fn smart_resolve_context_dependent_help( fn smart_resolve_context_dependent_help(
&mut self, &mut self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
span: Span, span: Span,
source: PathSource<'_>, source: PathSource<'_>,
path: &[Segment], path: &[Segment],
@ -1421,7 +1432,8 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
let ns = source.namespace(); let ns = source.namespace();
let is_expected = &|res| source.is_expected(res); let is_expected = &|res| source.is_expected(res);
let path_sep = |this: &mut Self, err: &mut Diagnostic, expr: &Expr, kind: DefKind| { let path_sep =
|this: &mut Self, err: &mut DiagnosticBuilder<'_>, expr: &Expr, kind: DefKind| {
const MESSAGE: &str = "use the path separator to refer to an item"; const MESSAGE: &str = "use the path separator to refer to an item";
let (lhs_span, rhs_span) = match &expr.kind { let (lhs_span, rhs_span) = match &expr.kind {
@ -1442,7 +1454,8 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
true true
} else if kind == DefKind::Struct } else if kind == DefKind::Struct
&& let Some(lhs_source_span) = lhs_span.find_ancestor_inside(expr.span) && let Some(lhs_source_span) = lhs_span.find_ancestor_inside(expr.span)
&& let Ok(snippet) = this.r.tcx.sess.source_map().span_to_snippet(lhs_source_span) && let Ok(snippet) =
this.r.tcx.sess.source_map().span_to_snippet(lhs_source_span)
{ {
// The LHS is a type that originates from a macro call. // The LHS is a type that originates from a macro call.
// We have to add angle brackets around it. // We have to add angle brackets around it.
@ -1464,7 +1477,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
} }
}; };
let find_span = |source: &PathSource<'_>, err: &mut Diagnostic| { let find_span = |source: &PathSource<'_>, err: &mut DiagnosticBuilder<'_>| {
match source { match source {
PathSource::Expr(Some(Expr { span, kind: ExprKind::Call(_, _), .. })) PathSource::Expr(Some(Expr { span, kind: ExprKind::Call(_, _), .. }))
| PathSource::TupleStruct(span, _) => { | PathSource::TupleStruct(span, _) => {
@ -1820,7 +1833,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
fn suggest_alternative_construction_methods( fn suggest_alternative_construction_methods(
&mut self, &mut self,
def_id: DefId, def_id: DefId,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
path_span: Span, path_span: Span,
call_span: Span, call_span: Span,
args: &[P<Expr>], args: &[P<Expr>],
@ -2250,7 +2263,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
// try to give a suggestion for this pattern: `name = blah`, which is common in other languages // try to give a suggestion for this pattern: `name = blah`, which is common in other languages
// suggest `let name = blah` to introduce a new binding // suggest `let name = blah` to introduce a new binding
fn let_binding_suggestion(&mut self, err: &mut Diagnostic, ident_span: Span) -> bool { fn let_binding_suggestion(
&mut self,
err: &mut DiagnosticBuilder<'_>,
ident_span: Span,
) -> bool {
if let Some(Expr { kind: ExprKind::Assign(lhs, ..), .. }) = if let Some(Expr { kind: ExprKind::Assign(lhs, ..), .. }) =
self.diagnostic_metadata.in_assignment self.diagnostic_metadata.in_assignment
&& let ast::ExprKind::Path(None, ref path) = lhs.kind && let ast::ExprKind::Path(None, ref path) = lhs.kind
@ -2351,7 +2368,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
/// Adds a suggestion for using an enum's variant when an enum is used instead. /// Adds a suggestion for using an enum's variant when an enum is used instead.
fn suggest_using_enum_variant( fn suggest_using_enum_variant(
&mut self, &mut self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
source: PathSource<'_>, source: PathSource<'_>,
def_id: DefId, def_id: DefId,
span: Span, span: Span,
@ -2727,9 +2744,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
fn suggest_introducing_lifetime( fn suggest_introducing_lifetime(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
name: Option<&str>, name: Option<&str>,
suggest: impl Fn(&mut Diagnostic, bool, Span, Cow<'static, str>, String) -> bool, suggest: impl Fn(&mut DiagnosticBuilder<'_>, bool, Span, Cow<'static, str>, String) -> bool,
) { ) {
let mut suggest_note = true; let mut suggest_note = true;
for rib in self.lifetime_ribs.iter().rev() { for rib in self.lifetime_ribs.iter().rev() {
@ -2887,7 +2904,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
fn add_missing_lifetime_specifiers_label( fn add_missing_lifetime_specifiers_label(
&mut self, &mut self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
lifetime_refs: Vec<MissingLifetime>, lifetime_refs: Vec<MissingLifetime>,
function_param_lifetimes: Option<(Vec<MissingLifetime>, Vec<ElisionFnParameter>)>, function_param_lifetimes: Option<(Vec<MissingLifetime>, Vec<ElisionFnParameter>)>,
) { ) {

View file

@ -2468,6 +2468,9 @@ pub fn parse_externs(
)); ));
let adjusted_name = name.replace('-', "_"); let adjusted_name = name.replace('-', "_");
if is_ascii_ident(&adjusted_name) { if is_ascii_ident(&adjusted_name) {
// FIXME: make this translatable
#[allow(rustc::diagnostic_outside_of_impl)]
#[allow(rustc::untranslatable_diagnostic)]
error.help(format!( error.help(format!(
"consider replacing the dashes with underscores: `{adjusted_name}`" "consider replacing the dashes with underscores: `{adjusted_name}`"
)); ));

View file

@ -15,7 +15,8 @@ use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc}; use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc};
use rustc_errors::{emitter::SilentEmitter, DiagCtxt}; use rustc_errors::{emitter::SilentEmitter, DiagCtxt};
use rustc_errors::{ use rustc_errors::{
fallback_fluent_bundle, Diagnostic, DiagnosticBuilder, DiagnosticMessage, MultiSpan, StashKey, fallback_fluent_bundle, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, MultiSpan,
StashKey,
}; };
use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures}; use rustc_feature::{find_feature_issue, GateIssue, UnstableFeatures};
use rustc_span::edition::Edition; use rustc_span::edition::Edition;
@ -156,7 +157,11 @@ pub fn feature_warn_issue(
} }
/// Adds the diagnostics for a feature to an existing error. /// Adds the diagnostics for a feature to an existing error.
pub fn add_feature_diagnostics(err: &mut Diagnostic, sess: &Session, feature: Symbol) { pub fn add_feature_diagnostics<G: EmissionGuarantee>(
err: &mut DiagnosticBuilder<'_, G>,
sess: &Session,
feature: Symbol,
) {
add_feature_diagnostics_for_issue(err, sess, feature, GateIssue::Language, false); add_feature_diagnostics_for_issue(err, sess, feature, GateIssue::Language, false);
} }
@ -165,8 +170,8 @@ pub fn add_feature_diagnostics(err: &mut Diagnostic, sess: &Session, feature: Sy
/// This variant allows you to control whether it is a library or language feature. /// This variant allows you to control whether it is a library or language feature.
/// Almost always, you want to use this for a language feature. If so, prefer /// Almost always, you want to use this for a language feature. If so, prefer
/// `add_feature_diagnostics`. /// `add_feature_diagnostics`.
pub fn add_feature_diagnostics_for_issue( pub fn add_feature_diagnostics_for_issue<G: EmissionGuarantee>(
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_, G>,
sess: &Session, sess: &Session,
feature: Symbol, feature: Symbol,
issue: GateIssue, issue: GateIssue,

View file

@ -1,7 +1,7 @@
use crate::fluent_generated as fluent; use crate::fluent_generated as fluent;
use rustc_errors::{ use rustc_errors::{
codes::*, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder, codes::*, AddToDiagnostic, Applicability, DiagCtxt, DiagnosticBuilder, EmissionGuarantee,
EmissionGuarantee, IntoDiagnostic, Level, SubdiagnosticMessageOp, IntoDiagnostic, Level, SubdiagnosticMessageOp,
}; };
use rustc_macros::Diagnostic; use rustc_macros::Diagnostic;
use rustc_middle::ty::{self, ClosureKind, PolyTraitRef, Ty}; use rustc_middle::ty::{self, ClosureKind, PolyTraitRef, Ty};
@ -102,7 +102,11 @@ pub enum AdjustSignatureBorrow {
} }
impl AddToDiagnostic for AdjustSignatureBorrow { impl AddToDiagnostic for AdjustSignatureBorrow {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
_f: F,
) {
match self { match self {
AdjustSignatureBorrow::Borrow { to_borrow } => { AdjustSignatureBorrow::Borrow { to_borrow } => {
diag.arg("len", to_borrow.len()); diag.arg("len", to_borrow.len());

View file

@ -18,7 +18,7 @@ use crate::traits::{
Obligation, ObligationCause, PredicateObligation, PredicateObligations, SelectionContext, Obligation, ObligationCause, PredicateObligation, PredicateObligations, SelectionContext,
}; };
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::Diagnostic; use rustc_errors::{DiagnosticBuilder, EmissionGuarantee};
use rustc_hir::def::DefKind; use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt}; use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, TyCtxtInferExt};
@ -58,7 +58,7 @@ pub struct OverlapResult<'tcx> {
pub involves_placeholder: bool, pub involves_placeholder: bool,
} }
pub fn add_placeholder_note(err: &mut Diagnostic) { pub fn add_placeholder_note<G: EmissionGuarantee>(err: &mut DiagnosticBuilder<'_, G>) {
err.note( err.note(
"this behavior recently changed as a result of a bug fix; \ "this behavior recently changed as a result of a bug fix; \
see rust-lang/rust#56105 for details", see rust-lang/rust#56105 for details",

View file

@ -13,7 +13,7 @@ use hir::def::CtorOf;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::{ use rustc_errors::{
codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, codes::*, pluralize, struct_span_code_err, Applicability, DiagnosticBuilder, EmissionGuarantee,
MultiSpan, Style, SuggestionStyle, MultiSpan, Style, SuggestionStyle,
}; };
use rustc_hir as hir; use rustc_hir as hir;
@ -116,12 +116,12 @@ fn predicate_constraint(generics: &hir::Generics<'_>, pred: ty::Predicate<'_>) -
/// Type parameter needs more bounds. The trivial case is `T` `where T: Bound`, but /// Type parameter needs more bounds. The trivial case is `T` `where T: Bound`, but
/// it can also be an `impl Trait` param that needs to be decomposed to a type /// it can also be an `impl Trait` param that needs to be decomposed to a type
/// param for cleaner code. /// param for cleaner code.
pub fn suggest_restriction<'tcx>( pub fn suggest_restriction<'tcx, G: EmissionGuarantee>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
item_id: LocalDefId, item_id: LocalDefId,
hir_generics: &hir::Generics<'tcx>, hir_generics: &hir::Generics<'tcx>,
msg: &str, msg: &str,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_, G>,
fn_sig: Option<&hir::FnSig<'_>>, fn_sig: Option<&hir::FnSig<'_>>,
projection: Option<&ty::AliasTy<'_>>, projection: Option<&ty::AliasTy<'_>>,
trait_pred: ty::PolyTraitPredicate<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>,
@ -240,7 +240,7 @@ pub fn suggest_restriction<'tcx>(
impl<'tcx> TypeErrCtxt<'_, 'tcx> { impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn suggest_restricting_param_bound( fn suggest_restricting_param_bound(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
trait_pred: ty::PolyTraitPredicate<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>,
associated_ty: Option<(&'static str, Ty<'tcx>)>, associated_ty: Option<(&'static str, Ty<'tcx>)>,
mut body_id: LocalDefId, mut body_id: LocalDefId,
@ -450,7 +450,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn suggest_dereferences( fn suggest_dereferences(
&self, &self,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
trait_pred: ty::PolyTraitPredicate<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>,
) -> bool { ) -> bool {
let mut code = obligation.cause.code(); let mut code = obligation.cause.code();
@ -743,10 +743,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn get_closure_name( fn get_closure_name(
&self, &self,
def_id: DefId, def_id: DefId,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
msg: Cow<'static, str>, msg: Cow<'static, str>,
) -> Option<Symbol> { ) -> Option<Symbol> {
let get_name = |err: &mut Diagnostic, kind: &hir::PatKind<'_>| -> Option<Symbol> { let get_name =
|err: &mut DiagnosticBuilder<'_>, kind: &hir::PatKind<'_>| -> Option<Symbol> {
// Get the local name of this closure. This can be inaccurate because // Get the local name of this closure. This can be inaccurate because
// of the possibility of reassignment, but this should be good enough. // of the possibility of reassignment, but this should be good enough.
match &kind { match &kind {
@ -778,7 +779,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn suggest_fn_call( fn suggest_fn_call(
&self, &self,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
trait_pred: ty::PolyTraitPredicate<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>,
) -> bool { ) -> bool {
// It doesn't make sense to make this suggestion outside of typeck... // It doesn't make sense to make this suggestion outside of typeck...
@ -894,7 +895,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn check_for_binding_assigned_block_without_tail_expression( fn check_for_binding_assigned_block_without_tail_expression(
&self, &self,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
trait_pred: ty::PolyTraitPredicate<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>,
) { ) {
let mut span = obligation.cause.span; let mut span = obligation.cause.span;
@ -971,7 +972,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn suggest_add_clone_to_arg( fn suggest_add_clone_to_arg(
&self, &self,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
trait_pred: ty::PolyTraitPredicate<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>,
) -> bool { ) -> bool {
let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty()); let self_ty = self.resolve_vars_if_possible(trait_pred.self_ty());
@ -1156,7 +1157,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn suggest_add_reference_to_arg( fn suggest_add_reference_to_arg(
&self, &self,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
poly_trait_pred: ty::PolyTraitPredicate<'tcx>, poly_trait_pred: ty::PolyTraitPredicate<'tcx>,
has_custom_message: bool, has_custom_message: bool,
) -> bool { ) -> bool {
@ -1374,7 +1375,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// Suggest borrowing the type // Suggest borrowing the type
fn suggest_borrowing_for_object_cast( fn suggest_borrowing_for_object_cast(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
target_ty: Ty<'tcx>, target_ty: Ty<'tcx>,
@ -1410,7 +1411,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn suggest_remove_reference( fn suggest_remove_reference(
&self, &self,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
trait_pred: ty::PolyTraitPredicate<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>,
) -> bool { ) -> bool {
let mut span = obligation.cause.span; let mut span = obligation.cause.span;
@ -1529,7 +1530,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
false false
} }
fn suggest_remove_await(&self, obligation: &PredicateObligation<'tcx>, err: &mut Diagnostic) { fn suggest_remove_await(
&self,
obligation: &PredicateObligation<'tcx>,
err: &mut DiagnosticBuilder<'_>,
) {
let hir = self.tcx.hir(); let hir = self.tcx.hir();
if let ObligationCauseCode::AwaitableExpr(hir_id) = obligation.cause.code().peel_derives() if let ObligationCauseCode::AwaitableExpr(hir_id) = obligation.cause.code().peel_derives()
&& let hir::Node::Expr(expr) = self.tcx.hir_node(*hir_id) && let hir::Node::Expr(expr) = self.tcx.hir_node(*hir_id)
@ -1599,7 +1604,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn suggest_change_mut( fn suggest_change_mut(
&self, &self,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
trait_pred: ty::PolyTraitPredicate<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>,
) { ) {
let points_at_arg = matches!( let points_at_arg = matches!(
@ -1677,7 +1682,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn suggest_semicolon_removal( fn suggest_semicolon_removal(
&self, &self,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
span: Span, span: Span,
trait_pred: ty::PolyTraitPredicate<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>,
) -> bool { ) -> bool {
@ -1731,7 +1736,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
/// emitted. /// emitted.
fn suggest_impl_trait( fn suggest_impl_trait(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
trait_pred: ty::PolyTraitPredicate<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>,
) -> bool { ) -> bool {
@ -1913,7 +1918,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn note_conflicting_fn_args( fn note_conflicting_fn_args(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
cause: &ObligationCauseCode<'tcx>, cause: &ObligationCauseCode<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
found: Ty<'tcx>, found: Ty<'tcx>,
@ -2120,7 +2125,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn suggest_fully_qualified_path( fn suggest_fully_qualified_path(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
item_def_id: DefId, item_def_id: DefId,
span: Span, span: Span,
trait_ref: DefId, trait_ref: DefId,
@ -2185,9 +2190,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
/// ///
/// Returns `true` if an async-await specific note was added to the diagnostic. /// Returns `true` if an async-await specific note was added to the diagnostic.
#[instrument(level = "debug", skip_all, fields(?obligation.predicate, ?obligation.cause.span))] #[instrument(level = "debug", skip_all, fields(?obligation.predicate, ?obligation.cause.span))]
fn maybe_note_obligation_cause_for_async_await( fn maybe_note_obligation_cause_for_async_await<G: EmissionGuarantee>(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_, G>,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
) -> bool { ) -> bool {
let hir = self.tcx.hir(); let hir = self.tcx.hir();
@ -2421,9 +2426,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
/// Unconditionally adds the diagnostic note described in /// Unconditionally adds the diagnostic note described in
/// `maybe_note_obligation_cause_for_async_await`'s documentation comment. /// `maybe_note_obligation_cause_for_async_await`'s documentation comment.
#[instrument(level = "debug", skip_all)] #[instrument(level = "debug", skip_all)]
fn note_obligation_cause_for_async_await( fn note_obligation_cause_for_async_await<G: EmissionGuarantee>(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_, G>,
interior_or_upvar_span: CoroutineInteriorOrUpvar, interior_or_upvar_span: CoroutineInteriorOrUpvar,
is_async: bool, is_async: bool,
outer_coroutine: Option<DefId>, outer_coroutine: Option<DefId>,
@ -2656,10 +2661,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
); );
} }
fn note_obligation_cause_code<T>( fn note_obligation_cause_code<G: EmissionGuarantee, T>(
&self, &self,
body_id: LocalDefId, body_id: LocalDefId,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_, G>,
predicate: T, predicate: T,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
cause_code: &ObligationCauseCode<'tcx>, cause_code: &ObligationCauseCode<'tcx>,
@ -3507,7 +3512,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
)] )]
fn suggest_await_before_try( fn suggest_await_before_try(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
trait_pred: ty::PolyTraitPredicate<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>,
span: Span, span: Span,
@ -3565,7 +3570,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn suggest_floating_point_literal( fn suggest_floating_point_literal(
&self, &self,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
trait_ref: &ty::PolyTraitRef<'tcx>, trait_ref: &ty::PolyTraitRef<'tcx>,
) { ) {
let rhs_span = match obligation.cause.code() { let rhs_span = match obligation.cause.code() {
@ -3589,7 +3594,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn suggest_derive( fn suggest_derive(
&self, &self,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
trait_pred: ty::PolyTraitPredicate<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>,
) { ) {
let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) else { let Some(diagnostic_name) = self.tcx.get_diagnostic_name(trait_pred.def_id()) else {
@ -3655,7 +3660,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn suggest_dereferencing_index( fn suggest_dereferencing_index(
&self, &self,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
trait_pred: ty::PolyTraitPredicate<'tcx>, trait_pred: ty::PolyTraitPredicate<'tcx>,
) { ) {
if let ObligationCauseCode::ImplDerivedObligation(_) = obligation.cause.code() if let ObligationCauseCode::ImplDerivedObligation(_) = obligation.cause.code()
@ -3675,10 +3680,10 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
} }
fn note_function_argument_obligation( fn note_function_argument_obligation<G: EmissionGuarantee>(
&self, &self,
body_id: LocalDefId, body_id: LocalDefId,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_, G>,
arg_hir_id: HirId, arg_hir_id: HirId,
parent_code: &ObligationCauseCode<'tcx>, parent_code: &ObligationCauseCode<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
@ -3860,11 +3865,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
} }
fn suggest_option_method_if_applicable( fn suggest_option_method_if_applicable<G: EmissionGuarantee>(
&self, &self,
failed_pred: ty::Predicate<'tcx>, failed_pred: ty::Predicate<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_, G>,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
) { ) {
let tcx = self.tcx; let tcx = self.tcx;
@ -3934,7 +3939,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
} }
fn look_for_iterator_item_mistakes( fn look_for_iterator_item_mistakes<G: EmissionGuarantee>(
&self, &self,
assocs_in_this_method: &[Option<(Span, (DefId, Ty<'tcx>))>], assocs_in_this_method: &[Option<(Span, (DefId, Ty<'tcx>))>],
typeck_results: &TypeckResults<'tcx>, typeck_results: &TypeckResults<'tcx>,
@ -3942,7 +3947,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
path_segment: &hir::PathSegment<'_>, path_segment: &hir::PathSegment<'_>,
args: &[hir::Expr<'_>], args: &[hir::Expr<'_>],
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_, G>,
) { ) {
let tcx = self.tcx; let tcx = self.tcx;
// Special case for iterator chains, we look at potential failures of `Iterator::Item` // Special case for iterator chains, we look at potential failures of `Iterator::Item`
@ -4037,13 +4042,13 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
} }
fn point_at_chain( fn point_at_chain<G: EmissionGuarantee>(
&self, &self,
expr: &hir::Expr<'_>, expr: &hir::Expr<'_>,
typeck_results: &TypeckResults<'tcx>, typeck_results: &TypeckResults<'tcx>,
type_diffs: Vec<TypeError<'tcx>>, type_diffs: Vec<TypeError<'tcx>>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_, G>,
) { ) {
let mut primary_spans = vec![]; let mut primary_spans = vec![];
let mut span_labels = vec![]; let mut span_labels = vec![];
@ -4279,7 +4284,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
/// the array into a slice. /// the array into a slice.
fn suggest_convert_to_slice( fn suggest_convert_to_slice(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>,
candidate_impls: &[ImplCandidate<'tcx>], candidate_impls: &[ImplCandidate<'tcx>],
@ -4351,7 +4356,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn explain_hrtb_projection( fn explain_hrtb_projection(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
pred: ty::PolyTraitPredicate<'tcx>, pred: ty::PolyTraitPredicate<'tcx>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
cause: &ObligationCause<'tcx>, cause: &ObligationCause<'tcx>,
@ -4417,7 +4422,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn suggest_desugaring_async_fn_in_trait( fn suggest_desugaring_async_fn_in_trait(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
trait_ref: ty::PolyTraitRef<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>,
) { ) {
// Don't suggest if RTN is active -- we should prefer a where-clause bound instead. // Don't suggest if RTN is active -- we should prefer a where-clause bound instead.
@ -4508,7 +4513,7 @@ fn hint_missing_borrow<'tcx>(
found: Ty<'tcx>, found: Ty<'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
found_node: Node<'_>, found_node: Node<'_>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
) { ) {
if matches!(found_node, Node::TraitItem(..)) { if matches!(found_node, Node::TraitItem(..)) {
return; return;
@ -4867,9 +4872,9 @@ pub fn suggest_desugaring_async_fn_to_impl_future_in_trait<'tcx>(
/// On `impl` evaluation cycles, look for `Self::AssocTy` restrictions in `where` clauses, explain /// On `impl` evaluation cycles, look for `Self::AssocTy` restrictions in `where` clauses, explain
/// they are not allowed and if possible suggest alternatives. /// they are not allowed and if possible suggest alternatives.
fn point_at_assoc_type_restriction( fn point_at_assoc_type_restriction<G: EmissionGuarantee>(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_, G>,
self_ty_str: &str, self_ty_str: &str,
trait_name: &str, trait_name: &str,
predicate: ty::Predicate<'_>, predicate: ty::Predicate<'_>,

View file

@ -21,8 +21,8 @@ use crate::traits::{
}; };
use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
use rustc_errors::{ use rustc_errors::{
codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, codes::*, pluralize, struct_span_code_err, Applicability, DiagnosticBuilder, ErrorGuaranteed,
ErrorGuaranteed, MultiSpan, StashKey, StringPart, MultiSpan, StashKey, StringPart,
}; };
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{DefKind, Namespace, Res}; use rustc_hir::def::{DefKind, Namespace, Res};
@ -185,7 +185,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
predicate: &T, predicate: &T,
span: Span, span: Span,
suggest_increasing_limit: bool, suggest_increasing_limit: bool,
mutate: impl FnOnce(&mut Diagnostic), mutate: impl FnOnce(&mut DiagnosticBuilder<'_>),
) -> ! ) -> !
where where
T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>, T: fmt::Display + TypeFoldable<TyCtxt<'tcx>> + Print<'tcx, FmtPrinter<'tcx, 'tcx>>,
@ -272,7 +272,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
); );
} }
fn suggest_new_overflow_limit(&self, err: &mut Diagnostic) { fn suggest_new_overflow_limit(&self, err: &mut DiagnosticBuilder<'_>) {
let suggested_limit = match self.tcx.recursion_limit() { let suggested_limit = match self.tcx.recursion_limit() {
Limit(0) => Limit(2), Limit(0) => Limit(2),
limit => limit * 2, limit => limit * 2,
@ -1020,7 +1020,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
&self, &self,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
trait_ref: ty::TraitRef<'tcx>, trait_ref: ty::TraitRef<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
) -> bool { ) -> bool {
let span = obligation.cause.span; let span = obligation.cause.span;
struct V<'v> { struct V<'v> {
@ -1810,7 +1810,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
impl_candidates: &[ImplCandidate<'tcx>], impl_candidates: &[ImplCandidate<'tcx>],
trait_ref: ty::PolyTraitRef<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>,
body_def_id: LocalDefId, body_def_id: LocalDefId,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
other: bool, other: bool,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
) -> bool { ) -> bool {
@ -1897,7 +1897,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
let other = if other { "other " } else { "" }; let other = if other { "other " } else { "" };
let report = |candidates: Vec<TraitRef<'tcx>>, err: &mut Diagnostic| { let report = |candidates: Vec<TraitRef<'tcx>>, err: &mut DiagnosticBuilder<'_>| {
if candidates.is_empty() { if candidates.is_empty() {
return false; return false;
} }
@ -2032,7 +2032,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
trait_predicate: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>, trait_predicate: ty::Binder<'tcx, ty::TraitPredicate<'tcx>>,
body_def_id: LocalDefId, body_def_id: LocalDefId,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
) { ) {
// This is *almost* equivalent to // This is *almost* equivalent to
// `obligation.cause.code().peel_derives()`, but it gives us the // `obligation.cause.code().peel_derives()`, but it gives us the
@ -2103,7 +2103,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
/// a probable version mismatch is added to `err` /// a probable version mismatch is added to `err`
fn note_version_mismatch( fn note_version_mismatch(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
trait_ref: &ty::PolyTraitRef<'tcx>, trait_ref: &ty::PolyTraitRef<'tcx>,
) -> bool { ) -> bool {
let get_trait_impls = |trait_def_id| { let get_trait_impls = |trait_def_id| {
@ -2572,7 +2572,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn annotate_source_of_ambiguity( fn annotate_source_of_ambiguity(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
ambiguities: &[ambiguity::Ambiguity], ambiguities: &[ambiguity::Ambiguity],
predicate: ty::Predicate<'tcx>, predicate: ty::Predicate<'tcx>,
) { ) {
@ -2715,7 +2715,11 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}) })
} }
fn note_obligation_cause(&self, err: &mut Diagnostic, obligation: &PredicateObligation<'tcx>) { fn note_obligation_cause(
&self,
err: &mut DiagnosticBuilder<'_>,
obligation: &PredicateObligation<'tcx>,
) {
// First, attempt to add note to this error with an async-await-specific // First, attempt to add note to this error with an async-await-specific
// message, and fall back to regular note otherwise. // message, and fall back to regular note otherwise.
if !self.maybe_note_obligation_cause_for_async_await(err, obligation) { if !self.maybe_note_obligation_cause_for_async_await(err, obligation) {
@ -2744,7 +2748,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
#[instrument(level = "debug", skip_all)] #[instrument(level = "debug", skip_all)]
fn suggest_unsized_bound_if_applicable( fn suggest_unsized_bound_if_applicable(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
) { ) {
let ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) = let ty::PredicateKind::Clause(ty::ClauseKind::Trait(pred)) =
@ -2770,7 +2774,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
} }
#[instrument(level = "debug", skip_all)] #[instrument(level = "debug", skip_all)]
fn maybe_suggest_unsized_generics(&self, err: &mut Diagnostic, span: Span, node: Node<'tcx>) { fn maybe_suggest_unsized_generics(
&self,
err: &mut DiagnosticBuilder<'_>,
span: Span,
node: Node<'tcx>,
) {
let Some(generics) = node.generics() else { let Some(generics) = node.generics() else {
return; return;
}; };
@ -2822,7 +2831,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn maybe_indirection_for_unsized( fn maybe_indirection_for_unsized(
&self, &self,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
item: &Item<'tcx>, item: &Item<'tcx>,
param: &GenericParam<'tcx>, param: &GenericParam<'tcx>,
) -> bool { ) -> bool {
@ -3016,7 +3025,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn add_tuple_trait_message( fn add_tuple_trait_message(
&self, &self,
obligation_cause_code: &ObligationCauseCode<'tcx>, obligation_cause_code: &ObligationCauseCode<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
) { ) {
match obligation_cause_code { match obligation_cause_code {
ObligationCauseCode::RustCall => { ObligationCauseCode::RustCall => {
@ -3041,7 +3050,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
obligation: &PredicateObligation<'tcx>, obligation: &PredicateObligation<'tcx>,
trait_ref: ty::PolyTraitRef<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>,
trait_predicate: &ty::PolyTraitPredicate<'tcx>, trait_predicate: &ty::PolyTraitPredicate<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
span: Span, span: Span,
is_fn_trait: bool, is_fn_trait: bool,
suggested: bool, suggested: bool,
@ -3122,7 +3131,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn add_help_message_for_fn_trait( fn add_help_message_for_fn_trait(
&self, &self,
trait_ref: ty::PolyTraitRef<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_>,
implemented_kind: ty::ClosureKind, implemented_kind: ty::ClosureKind,
params: ty::Binder<'tcx, Ty<'tcx>>, params: ty::Binder<'tcx, Ty<'tcx>>,
) { ) {
@ -3178,7 +3187,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
fn maybe_add_note_for_unsatisfied_const( fn maybe_add_note_for_unsatisfied_const(
&self, &self,
_trait_predicate: &ty::PolyTraitPredicate<'tcx>, _trait_predicate: &ty::PolyTraitPredicate<'tcx>,
_err: &mut Diagnostic, _err: &mut DiagnosticBuilder<'_>,
_span: Span, _span: Span,
) -> UnsatisfiedConst { ) -> UnsatisfiedConst {
let unsatisfied_const = UnsatisfiedConst(false); let unsatisfied_const = UnsatisfiedConst(false);

View file

@ -29,7 +29,7 @@ use crate::traits::ProjectionCacheKey;
use crate::traits::Unimplemented; use crate::traits::Unimplemented;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_data_structures::stack::ensure_sufficient_stack; use rustc_data_structures::stack::ensure_sufficient_stack;
use rustc_errors::Diagnostic; use rustc_errors::{DiagnosticBuilder, EmissionGuarantee};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_infer::infer::BoundRegionConversionTime; use rustc_infer::infer::BoundRegionConversionTime;
@ -70,7 +70,10 @@ pub enum IntercrateAmbiguityCause<'tcx> {
impl<'tcx> IntercrateAmbiguityCause<'tcx> { impl<'tcx> IntercrateAmbiguityCause<'tcx> {
/// Emits notes when the overlap is caused by complex intercrate ambiguities. /// Emits notes when the overlap is caused by complex intercrate ambiguities.
/// See #23980 for details. /// See #23980 for details.
pub fn add_intercrate_ambiguity_hint(&self, err: &mut Diagnostic) { pub fn add_intercrate_ambiguity_hint<G: EmissionGuarantee>(
&self,
err: &mut DiagnosticBuilder<'_, G>,
) {
err.note(self.intercrate_ambiguity_hint()); err.note(self.intercrate_ambiguity_hint());
} }

View file

@ -20,7 +20,7 @@ use crate::traits::{
self, coherence, FutureCompatOverlapErrorKind, ObligationCause, ObligationCtxt, self, coherence, FutureCompatOverlapErrorKind, ObligationCause, ObligationCtxt,
}; };
use rustc_data_structures::fx::FxIndexSet; use rustc_data_structures::fx::FxIndexSet;
use rustc_errors::{codes::*, DelayDm, Diagnostic}; use rustc_errors::{codes::*, DelayDm, DiagnosticBuilder, EmissionGuarantee};
use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt}; use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitableExt};
use rustc_middle::ty::{GenericArgs, GenericArgsRef}; use rustc_middle::ty::{GenericArgs, GenericArgsRef};
@ -395,11 +395,11 @@ fn report_conflicting_impls<'tcx>(
// Work to be done after we've built the DiagnosticBuilder. We have to define it // Work to be done after we've built the DiagnosticBuilder. We have to define it
// now because the lint emit methods don't return back the DiagnosticBuilder // now because the lint emit methods don't return back the DiagnosticBuilder
// that's passed in. // that's passed in.
fn decorate<'tcx>( fn decorate<'tcx, G: EmissionGuarantee>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
overlap: &OverlapError<'tcx>, overlap: &OverlapError<'tcx>,
impl_span: Span, impl_span: Span,
err: &mut Diagnostic, err: &mut DiagnosticBuilder<'_, G>,
) { ) {
if (overlap.trait_ref, overlap.self_ty).references_error() { if (overlap.trait_ref, overlap.self_ty).references_error() {
err.downgrade_to_delayed_bug(); err.downgrade_to_delayed_bug();

View file

@ -3,7 +3,7 @@ use std::collections::BTreeMap;
use super::NormalizeExt; use super::NormalizeExt;
use super::{ObligationCause, PredicateObligation, SelectionContext}; use super::{ObligationCause, PredicateObligation, SelectionContext};
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
use rustc_errors::Diagnostic; use rustc_errors::DiagnosticBuilder;
use rustc_hir::def_id::DefId; use rustc_hir::def_id::DefId;
use rustc_infer::infer::{InferCtxt, InferOk}; use rustc_infer::infer::{InferCtxt, InferOk};
use rustc_middle::ty::GenericArgsRef; use rustc_middle::ty::GenericArgsRef;
@ -46,7 +46,7 @@ impl<'tcx> TraitAliasExpansionInfo<'tcx> {
/// trait aliases. /// trait aliases.
pub fn label_with_exp_info( pub fn label_with_exp_info(
&self, &self,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_>,
top_label: &'static str, top_label: &'static str,
use_desc: &str, use_desc: &str,
) { ) {

View file

@ -8,7 +8,7 @@ use rustc_data_structures::{
fx::{FxHashMap, FxHashSet}, fx::{FxHashMap, FxHashSet},
intern::Interned, intern::Interned,
}; };
use rustc_errors::{Applicability, Diagnostic, DiagnosticMessage}; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticMessage};
use rustc_hir::def::Namespace::*; use rustc_hir::def::Namespace::*;
use rustc_hir::def::{DefKind, Namespace, PerNS}; use rustc_hir::def::{DefKind, Namespace, PerNS};
use rustc_hir::def_id::{DefId, CRATE_DEF_ID}; use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
@ -1173,7 +1173,8 @@ impl LinkCollector<'_, '_> {
) { ) {
// The resolved item did not match the disambiguator; give a better error than 'not found' // The resolved item did not match the disambiguator; give a better error than 'not found'
let msg = format!("incompatible link kind for `{path_str}`"); let msg = format!("incompatible link kind for `{path_str}`");
let callback = |diag: &mut Diagnostic, sp: Option<rustc_span::Span>, link_range| { let callback =
|diag: &mut DiagnosticBuilder<'_, ()>, sp: Option<rustc_span::Span>, link_range| {
let note = format!( let note = format!(
"this link resolved to {} {}, which is not {} {}", "this link resolved to {} {}, which is not {} {}",
resolved.article(), resolved.article(),
@ -1676,7 +1677,7 @@ fn report_diagnostic(
lint: &'static Lint, lint: &'static Lint,
msg: impl Into<DiagnosticMessage> + Display, msg: impl Into<DiagnosticMessage> + Display,
DiagnosticInfo { item, ori_link: _, dox, link_range }: &DiagnosticInfo<'_>, DiagnosticInfo { item, ori_link: _, dox, link_range }: &DiagnosticInfo<'_>,
decorate: impl FnOnce(&mut Diagnostic, Option<rustc_span::Span>, MarkdownLinkRange), decorate: impl FnOnce(&mut DiagnosticBuilder<'_, ()>, Option<rustc_span::Span>, MarkdownLinkRange),
) { ) {
let Some(hir_id) = DocContext::as_local_hir_id(tcx, item.item_id) else { let Some(hir_id) = DocContext::as_local_hir_id(tcx, item.item_id) else {
// If non-local, no need to check anything. // If non-local, no need to check anything.
@ -2124,7 +2125,7 @@ fn ambiguity_error(
/// disambiguator. /// disambiguator.
fn suggest_disambiguator( fn suggest_disambiguator(
res: Res, res: Res,
diag: &mut Diagnostic, diag: &mut DiagnosticBuilder<'_, ()>,
path_str: &str, path_str: &str,
link_range: MarkdownLinkRange, link_range: MarkdownLinkRange,
sp: Option<rustc_span::Span>, sp: Option<rustc_span::Span>,

View file

@ -4,7 +4,7 @@ use clippy_utils::expr_or_init;
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 @@ impl<'tcx> LateLintPass<'tcx> for IfLetMutex {
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 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
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 @@ use clippy_utils::{
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 crate::FxHashSet;
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 clippy_utils::{eq_expr_value, hash_expr, higher};
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 @@ declare_lint_pass!(MissingAssertsForIndexing => [MISSING_ASSERTS_FOR_INDEXING]);
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 @@ use clippy_utils::ty::{
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 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByValue {
&& !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 @@ where
/// 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,

View file

@ -683,7 +683,7 @@ fn indentation<T: LintContext>(cx: &T, span: Span) -> Option<String> {
}) })
} }
/// Convenience extension trait for `Diagnostic`. /// Convenience extension trait for `DiagnosticBuilder`.
pub trait DiagnosticExt<T: LintContext> { pub trait DiagnosticExt<T: LintContext> {
/// Suggests to add an attribute to an item. /// Suggests to add an attribute to an item.
/// ///
@ -731,7 +731,7 @@ pub trait DiagnosticExt<T: LintContext> {
fn suggest_remove_item(&mut self, cx: &T, item: Span, msg: &str, applicability: Applicability); fn suggest_remove_item(&mut self, cx: &T, item: Span, msg: &str, applicability: Applicability);
} }
impl<T: LintContext> DiagnosticExt<T> for rustc_errors::Diagnostic { impl<T: LintContext> DiagnosticExt<T> for rustc_errors::DiagnosticBuilder<'_, ()> {
fn suggest_item_with_attr<D: Display + ?Sized>( fn suggest_item_with_attr<D: Display + ?Sized>(
&mut self, &mut self,
cx: &T, cx: &T,

View file

@ -55,8 +55,11 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for TranslatableInIntoDiagn
pub struct UntranslatableInAddToDiagnostic; pub struct UntranslatableInAddToDiagnostic;
impl AddToDiagnostic for UntranslatableInAddToDiagnostic { impl AddToDiagnostic for UntranslatableInAddToDiagnostic {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
{ self,
diag: &mut DiagnosticBuilder<'_, G>,
f: F,
) {
diag.note("untranslatable diagnostic"); diag.note("untranslatable diagnostic");
//~^ ERROR diagnostics should be created using translatable messages //~^ ERROR diagnostics should be created using translatable messages
} }
@ -65,7 +68,11 @@ impl AddToDiagnostic for UntranslatableInAddToDiagnostic {
pub struct TranslatableInAddToDiagnostic; pub struct TranslatableInAddToDiagnostic;
impl AddToDiagnostic for TranslatableInAddToDiagnostic { impl AddToDiagnostic for TranslatableInAddToDiagnostic {
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) { fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
self,
diag: &mut DiagnosticBuilder<'_, G>,
f: F,
) {
diag.note(crate::fluent_generated::no_crate_note); diag.note(crate::fluent_generated::no_crate_note);
} }
} }

Some files were not shown because too many files have changed in this diff Show more