mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 08:13:41 +00:00
Reduce capabilities of Diagnostic
.
Currently many diagnostic modifier methods are available on both `Diagnostic` and `DiagnosticBuilder`. This commit removes most of them from `Diagnostic`. To minimize the diff size, it keeps them within `diagnostic.rs` but changes the surrounding `impl Diagnostic` block to `impl DiagnosticBuilder`. (I intend to move things around later, to give a more sensible code layout.) `Diagnostic` keeps a few methods that it still needs, like `sub`, `arg`, and `replace_args`. The `forward!` macro, which defined two additional methods per call (e.g. `note` and `with_note`), is replaced by the `with_fn!` macro, which defines one additional method per call (e.g. `with_note`). It's now also only used when necessary -- not all modifier methods currently need a `with_*` form. (New ones can be easily added as necessary.) All this also requires changing `trait AddToDiagnostic` so its methods take `DiagnosticBuilder` instead of `Diagnostic`, which leads to many mechanical changes. `SubdiagnosticMessageOp` gains a type parameter `G`. There are three subdiagnostics -- `DelayedAtWithoutNewline`, `DelayedAtWithNewline`, and `InvalidFlushedDelayedDiagnosticLevel` -- that are created within the diagnostics machinery and appended to external diagnostics. These are handled at the `Diagnostic` level, which means it's now hard to construct them via `derive(Diagnostic)`, so instead we construct them by hand. This has no effect on what they look like when printed. There are lots of new `allow` markers for `untranslatable_diagnostics` and `diagnostics_outside_of_impl`. This is because `#[rustc_lint_diagnostics]` annotations were present on the `Diagnostic` modifier methods, but missing from the `DiagnosticBuilder` modifier methods. They're now present.
This commit is contained in:
parent
b18f3e11fa
commit
f6f8779843
@ -1,5 +1,6 @@
|
||||
use rustc_errors::{
|
||||
codes::*, AddToDiagnostic, Diagnostic, DiagnosticArgFromDisplay, SubdiagnosticMessageOp,
|
||||
codes::*, AddToDiagnostic, DiagnosticArgFromDisplay, DiagnosticBuilder, EmissionGuarantee,
|
||||
SubdiagnosticMessageOp,
|
||||
};
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
use rustc_span::{symbol::Ident, Span, Symbol};
|
||||
@ -41,7 +42,11 @@ pub struct InvalidAbi {
|
||||
pub struct InvalidAbiReason(pub &'static str);
|
||||
|
||||
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)]
|
||||
diag.note(self.0);
|
||||
}
|
||||
|
@ -1,7 +1,10 @@
|
||||
//! Errors emitted by ast_passes.
|
||||
|
||||
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_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
|
||||
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, "");
|
||||
}
|
||||
}
|
||||
@ -729,7 +736,11 @@ pub struct 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("since", self.since);
|
||||
diag.help(fluent::ast_passes_stable_since);
|
||||
|
@ -22,6 +22,9 @@ macro_rules! gate {
|
||||
}};
|
||||
($visitor:expr, $feature:ident, $span:expr, $explain:expr, $help:expr) => {{
|
||||
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();
|
||||
}
|
||||
}};
|
||||
|
@ -251,6 +251,9 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
|
||||
hrtb_bounds.iter().for_each(|bound| {
|
||||
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(
|
||||
*trait_span,
|
||||
"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`.
|
||||
// FIXME: make this translatable
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
pub(crate) fn report_region_error(
|
||||
&mut self,
|
||||
fr: RegionVid,
|
||||
@ -685,12 +691,18 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
|
||||
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 {
|
||||
// FIXME: make this translatable
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
diag.span_label(
|
||||
outlived_fr_span,
|
||||
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 {
|
||||
diag.span_label(
|
||||
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();
|
||||
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(
|
||||
*span,
|
||||
format!(
|
||||
|
@ -2497,6 +2497,8 @@ mod diags {
|
||||
}
|
||||
for (_, (mut diag, count)) in std::mem::take(&mut self.diags.buffered_mut_errors) {
|
||||
if count > 10 {
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
diag.note(format!("...and {} other attempted mutable borrows", count - 10));
|
||||
}
|
||||
self.diags.buffered_diags.push(BufferedDiag::Error(diag));
|
||||
|
@ -1,6 +1,6 @@
|
||||
use rustc_errors::{
|
||||
codes::*, AddToDiagnostic, DiagCtxt, Diagnostic, DiagnosticBuilder, EmissionGuarantee,
|
||||
IntoDiagnostic, Level, MultiSpan, SingleLabelManySpans, SubdiagnosticMessageOp,
|
||||
codes::*, AddToDiagnostic, DiagCtxt, DiagnosticBuilder, EmissionGuarantee, IntoDiagnostic,
|
||||
Level, MultiSpan, SingleLabelManySpans, SubdiagnosticMessageOp,
|
||||
};
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
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
|
||||
// form of diagnostic.
|
||||
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);
|
||||
let msg = f(diag, crate::fluent_generated::builtin_macros_format_unused_arg.into());
|
||||
diag.span_label(self.span, msg);
|
||||
|
@ -1856,9 +1856,7 @@ impl SharedEmitterMain {
|
||||
Ok(SharedEmitterMessage::Diagnostic(diag)) => {
|
||||
let dcx = sess.dcx();
|
||||
let mut d = rustc_errors::Diagnostic::new_with_messages(diag.lvl, diag.msgs);
|
||||
if let Some(code) = diag.code {
|
||||
d.code(code);
|
||||
}
|
||||
d.code = diag.code; // may be `None`, that's ok
|
||||
d.replace_args(diag.args);
|
||||
dcx.emit_diagnostic(d);
|
||||
}
|
||||
|
@ -93,6 +93,9 @@ pub struct 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> {
|
||||
let FnCallNonConst { caller, callee, args, span, call_source, feature } = *self;
|
||||
let ConstCx { tcx, param_env, .. } = *ccx;
|
||||
@ -321,6 +324,8 @@ impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
|
||||
.dcx()
|
||||
.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() {
|
||||
err.help("const-stable functions can only call other const-stable functions");
|
||||
} else if ccx.tcx.sess.is_nightly_build() {
|
||||
@ -591,6 +596,8 @@ impl<'tcx> NonConstOp<'tcx> for StaticAccess {
|
||||
span,
|
||||
format!("referencing statics in {}s is unstable", ccx.const_kind(),),
|
||||
);
|
||||
// FIXME: make this translatable
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
err
|
||||
.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.");
|
||||
|
@ -12,6 +12,7 @@ use rustc_span::{Span, DUMMY_SP};
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::{self, Debug};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::panic::Location;
|
||||
|
||||
/// Error type for `Diagnostic`'s `suggestions` field, indicating that
|
||||
@ -71,17 +72,21 @@ where
|
||||
Self: Sized,
|
||||
{
|
||||
/// 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);
|
||||
}
|
||||
|
||||
/// Add a subdiagnostic to an existing diagnostic where `f` is invoked on every message used
|
||||
/// (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 =
|
||||
Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage;
|
||||
pub trait SubdiagnosticMessageOp<G> =
|
||||
Fn(&mut DiagnosticBuilder<'_, G>, SubdiagnosticMessage) -> SubdiagnosticMessage;
|
||||
|
||||
/// Trait implemented by lint types. This should not be implemented manually. Instead, use
|
||||
/// `#[derive(LintDiagnostic)]` -- see [rustc_macros::LintDiagnostic].
|
||||
@ -93,6 +98,10 @@ pub trait DecorateLint<'a, G: EmissionGuarantee> {
|
||||
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]
|
||||
#[derive(Clone, Debug, Encodable, Decodable)]
|
||||
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.
|
||||
///
|
||||
/// This can be useful in contexts where an error indicates a bug but
|
||||
@ -309,6 +402,7 @@ impl Diagnostic {
|
||||
self.level = Level::DelayedBug;
|
||||
}
|
||||
|
||||
with_fn! { with_span_label,
|
||||
/// Appends a labeled span to the diagnostic.
|
||||
///
|
||||
/// Labels are used to convey additional context for the diagnostic's primary span. They will
|
||||
@ -323,10 +417,12 @@ impl Diagnostic {
|
||||
/// primary.
|
||||
#[rustc_lint_diagnostics]
|
||||
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
|
||||
}
|
||||
} }
|
||||
|
||||
with_fn! { with_span_labels,
|
||||
/// Labels all the given spans with the provided label.
|
||||
/// See [`Self::span_label()`] for more information.
|
||||
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
|
||||
}
|
||||
} }
|
||||
|
||||
pub fn replace_span_with(&mut self, after: Span, keep_label: bool) -> &mut Self {
|
||||
let before = self.span.clone();
|
||||
@ -412,39 +508,40 @@ impl Diagnostic {
|
||||
self
|
||||
}
|
||||
|
||||
with_fn! { with_note,
|
||||
/// Add a note attached to this diagnostic.
|
||||
#[rustc_lint_diagnostics]
|
||||
pub fn note(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self {
|
||||
self.sub(Level::Note, msg, MultiSpan::new());
|
||||
self
|
||||
}
|
||||
} }
|
||||
|
||||
fn highlighted_note(&mut self, msg: Vec<StringPart>) -> &mut Self {
|
||||
self.sub_with_highlights(Level::Note, msg, MultiSpan::new());
|
||||
self
|
||||
}
|
||||
|
||||
/// 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's only printed once.
|
||||
pub fn note_once(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self {
|
||||
self.sub(Level::OnceNote, msg, MultiSpan::new());
|
||||
self
|
||||
}
|
||||
|
||||
with_fn! { with_span_note,
|
||||
/// 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]
|
||||
pub fn span_note<S: Into<MultiSpan>>(
|
||||
pub fn span_note(
|
||||
&mut self,
|
||||
sp: S,
|
||||
sp: impl Into<MultiSpan>,
|
||||
msg: impl Into<SubdiagnosticMessage>,
|
||||
) -> &mut Self {
|
||||
self.sub(Level::Note, msg, sp.into());
|
||||
self
|
||||
}
|
||||
} }
|
||||
|
||||
/// 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>>(
|
||||
&mut self,
|
||||
sp: S,
|
||||
@ -454,15 +551,16 @@ impl Diagnostic {
|
||||
self
|
||||
}
|
||||
|
||||
with_fn! { with_warn,
|
||||
/// Add a warning attached to this diagnostic.
|
||||
#[rustc_lint_diagnostics]
|
||||
pub fn warn(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self {
|
||||
self.sub(Level::Warning, msg, MultiSpan::new());
|
||||
self
|
||||
}
|
||||
} }
|
||||
|
||||
/// 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]
|
||||
pub fn span_warn<S: Into<MultiSpan>>(
|
||||
&mut self,
|
||||
@ -473,15 +571,15 @@ impl Diagnostic {
|
||||
self
|
||||
}
|
||||
|
||||
with_fn! { with_help,
|
||||
/// Add a help message attached to this diagnostic.
|
||||
#[rustc_lint_diagnostics]
|
||||
pub fn help(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self {
|
||||
self.sub(Level::Help, msg, MultiSpan::new());
|
||||
self
|
||||
}
|
||||
} }
|
||||
|
||||
/// Prints the span with a help above it.
|
||||
/// This is like [`Diagnostic::help()`], but it gets its own span.
|
||||
/// This is like [`DiagnosticBuilder::help()`], but it's only printed once.
|
||||
pub fn help_once(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self {
|
||||
self.sub(Level::OnceHelp, msg, MultiSpan::new());
|
||||
self
|
||||
@ -494,7 +592,7 @@ impl Diagnostic {
|
||||
}
|
||||
|
||||
/// 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]
|
||||
pub fn span_help<S: Into<MultiSpan>>(
|
||||
&mut self,
|
||||
@ -531,6 +629,7 @@ impl Diagnostic {
|
||||
}
|
||||
}
|
||||
|
||||
with_fn! { with_multipart_suggestion,
|
||||
/// Show a suggestion that has multiple parts to it.
|
||||
/// In other words, multiple changes need to be applied as part of this suggestion.
|
||||
pub fn multipart_suggestion(
|
||||
@ -545,7 +644,7 @@ impl Diagnostic {
|
||||
applicability,
|
||||
SuggestionStyle::ShowCode,
|
||||
)
|
||||
}
|
||||
} }
|
||||
|
||||
/// 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.
|
||||
@ -562,7 +661,8 @@ impl Diagnostic {
|
||||
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(
|
||||
&mut self,
|
||||
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.
|
||||
///
|
||||
/// In case of short messages and a simple suggestion, rustc displays it as a label:
|
||||
@ -651,9 +752,9 @@ impl Diagnostic {
|
||||
SuggestionStyle::ShowCode,
|
||||
);
|
||||
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(
|
||||
&mut self,
|
||||
sp: Span,
|
||||
@ -677,6 +778,7 @@ impl Diagnostic {
|
||||
self
|
||||
}
|
||||
|
||||
with_fn! { with_span_suggestion_verbose,
|
||||
/// Always show the suggested change.
|
||||
pub fn span_suggestion_verbose(
|
||||
&mut self,
|
||||
@ -693,10 +795,11 @@ impl Diagnostic {
|
||||
SuggestionStyle::ShowAlways,
|
||||
);
|
||||
self
|
||||
}
|
||||
} }
|
||||
|
||||
with_fn! { with_span_suggestions,
|
||||
/// 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(
|
||||
&mut self,
|
||||
sp: Span,
|
||||
@ -711,9 +814,8 @@ impl Diagnostic {
|
||||
applicability,
|
||||
SuggestionStyle::ShowCode,
|
||||
)
|
||||
}
|
||||
} }
|
||||
|
||||
/// [`Diagnostic::span_suggestions()`] but you can set the [`SuggestionStyle`].
|
||||
pub fn span_suggestions_with_style(
|
||||
&mut self,
|
||||
sp: Span,
|
||||
@ -743,7 +845,7 @@ impl Diagnostic {
|
||||
|
||||
/// Prints out a message with multiple suggested edits of the code, where each edit consists of
|
||||
/// multiple parts.
|
||||
/// See also [`Diagnostic::multipart_suggestion()`].
|
||||
/// See also [`DiagnosticBuilder::multipart_suggestion()`].
|
||||
pub fn multipart_suggestions(
|
||||
&mut self,
|
||||
msg: impl Into<SubdiagnosticMessage>,
|
||||
@ -785,6 +887,7 @@ impl Diagnostic {
|
||||
self
|
||||
}
|
||||
|
||||
with_fn! { with_span_suggestion_short,
|
||||
/// 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.
|
||||
///
|
||||
@ -804,7 +907,7 @@ impl Diagnostic {
|
||||
SuggestionStyle::HideCodeInline,
|
||||
);
|
||||
self
|
||||
}
|
||||
} }
|
||||
|
||||
/// Prints out a message for a suggestion without showing the suggested code.
|
||||
///
|
||||
@ -829,6 +932,7 @@ impl Diagnostic {
|
||||
self
|
||||
}
|
||||
|
||||
with_fn! { with_tool_only_span_suggestion,
|
||||
/// 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
|
||||
@ -849,7 +953,7 @@ impl Diagnostic {
|
||||
SuggestionStyle::CompletelyHidden,
|
||||
);
|
||||
self
|
||||
}
|
||||
} }
|
||||
|
||||
/// Add a subdiagnostic from a type that implements `Subdiagnostic` (see
|
||||
/// [rustc_macros::Subdiagnostic]). Performs eager translation of any translatable messages
|
||||
@ -868,45 +972,45 @@ impl Diagnostic {
|
||||
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();
|
||||
if let Some(span) = self.span.primary_span() {
|
||||
self.sort_span = span;
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
with_fn! { with_code,
|
||||
/// Add an error code.
|
||||
pub fn code(&mut self, code: ErrCode) -> &mut Self {
|
||||
self.code = Some(code);
|
||||
self
|
||||
}
|
||||
} }
|
||||
|
||||
with_fn! { with_primary_message,
|
||||
/// Add a primary message.
|
||||
pub fn primary_message(&mut self, msg: impl Into<DiagnosticMessage>) -> &mut Self {
|
||||
self.messages[0] = (msg.into(), Style::NoStyle);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn args(&self) -> impl Iterator<Item = DiagnosticArg<'_>> {
|
||||
self.args.iter()
|
||||
}
|
||||
} }
|
||||
|
||||
with_fn! { with_arg,
|
||||
/// Add an argument.
|
||||
pub fn arg(
|
||||
&mut self,
|
||||
name: impl Into<DiagnosticArgName>,
|
||||
arg: impl IntoDiagnosticArg,
|
||||
) -> &mut Self {
|
||||
self.args.insert(name.into(), arg.into_diagnostic_arg());
|
||||
self.deref_mut().arg(name, arg);
|
||||
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
|
||||
/// combining it with the primary message of the diagnostic (if translatable, otherwise it just
|
||||
@ -915,9 +1019,7 @@ impl Diagnostic {
|
||||
&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())
|
||||
self.deref().subdiagnostic_message_to_diagnostic_message(attr)
|
||||
}
|
||||
|
||||
/// 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`.
|
||||
pub 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);
|
||||
self.deref_mut().sub(level, message, span);
|
||||
}
|
||||
|
||||
/// Convenience function for internal use, clients should use one of the
|
||||
@ -946,7 +1040,9 @@ impl Diagnostic {
|
||||
let sub = SubDiagnostic { level, messages, span };
|
||||
self.children.push(sub);
|
||||
}
|
||||
}
|
||||
|
||||
impl Diagnostic {
|
||||
/// Fields used for Hash, and PartialEq trait
|
||||
fn keys(
|
||||
&self,
|
||||
|
@ -1,14 +1,8 @@
|
||||
use crate::diagnostic::IntoDiagnosticArg;
|
||||
use crate::{DiagCtxt, Level, MultiSpan, StashKey};
|
||||
use crate::{
|
||||
Diagnostic, DiagnosticMessage, DiagnosticStyledString, ErrCode, ErrorGuaranteed, ExplicitBug,
|
||||
SubdiagnosticMessage,
|
||||
DiagCtxt, Diagnostic, DiagnosticMessage, ErrorGuaranteed, ExplicitBug, Level, StashKey,
|
||||
};
|
||||
use rustc_lint_defs::Applicability;
|
||||
use rustc_span::source_map::Spanned;
|
||||
|
||||
use rustc_span::Span;
|
||||
use std::borrow::Cow;
|
||||
use std::fmt::{self, Debug};
|
||||
use std::marker::PhantomData;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
@ -35,6 +29,11 @@ where
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// `emit`, `cancel`, `delay_as_bug`, or `into_diagnostic`. A panic occurrs if a
|
||||
/// `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
|
||||
/// `PResult` type. In theory, return value optimization (RVO) should avoid
|
||||
/// 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
|
||||
@ -88,18 +89,21 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
|
||||
/// Takes the diagnostic. For use by methods that consume the
|
||||
/// DiagnosticBuilder: `emit`, `cancel`, etc. Afterwards, `drop` is the
|
||||
/// 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())
|
||||
}
|
||||
|
||||
/// 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();
|
||||
self.dcx.emit_diagnostic(diag);
|
||||
}
|
||||
|
||||
/// `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();
|
||||
|
||||
// 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> {
|
||||
type Target = Diagnostic;
|
||||
|
||||
@ -278,135 +248,6 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
|
||||
self.downgrade_to_delayed_bug();
|
||||
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> {
|
||||
|
@ -299,7 +299,11 @@ pub struct SingleLabelManySpans {
|
||||
pub label: &'static str,
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -312,23 +316,6 @@ pub struct ExpectedLifetimeParameter {
|
||||
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 {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
|
||||
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 {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
|
||||
DiagnosticArgValue::Str(Cow::from(self.to_string()))
|
||||
|
@ -599,7 +599,7 @@ impl Emitter for SilentEmitter {
|
||||
|
||||
fn emit_diagnostic(&mut self, mut diag: Diagnostic) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ pub use diagnostic_builder::{
|
||||
};
|
||||
pub use diagnostic_impls::{
|
||||
DiagnosticArgFromDisplay, DiagnosticSymbolList, ExpectedLifetimeParameter,
|
||||
IndicateAnonymousLifetime, InvalidFlushedDelayedDiagnosticLevel, SingleLabelManySpans,
|
||||
IndicateAnonymousLifetime, SingleLabelManySpans,
|
||||
};
|
||||
pub use emitter::ColorConfig;
|
||||
pub use rustc_error_messages::{
|
||||
@ -62,7 +62,6 @@ pub use snippet::Style;
|
||||
// See https://github.com/rust-lang/rust/pull/115393.
|
||||
pub use termcolor::{Color, ColorSpec, WriteColor};
|
||||
|
||||
use crate::diagnostic_impls::{DelayedAtWithNewline, DelayedAtWithoutNewline};
|
||||
use emitter::{is_case_difference, DynEmitter, Emitter, HumanEmitter};
|
||||
use registry::Registry;
|
||||
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
|
||||
@ -1395,9 +1394,8 @@ impl DiagCtxtInner {
|
||||
};
|
||||
diagnostic.children.extract_if(already_emitted_sub).for_each(|_| {});
|
||||
if already_emitted {
|
||||
diagnostic.note(
|
||||
"duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`",
|
||||
);
|
||||
let msg = "duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`";
|
||||
diagnostic.sub(Level::Note, msg, MultiSpan::new());
|
||||
}
|
||||
|
||||
if is_error {
|
||||
@ -1483,6 +1481,16 @@ impl DiagCtxtInner {
|
||||
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) {
|
||||
if self.delayed_bugs.is_empty() {
|
||||
return;
|
||||
@ -1527,17 +1535,14 @@ impl DiagCtxtInner {
|
||||
if bug.level != DelayedBug {
|
||||
// NOTE(eddyb) not panicking here because we're already producing
|
||||
// an ICE, and the more information the merrier.
|
||||
let subdiag = InvalidFlushedDelayedDiagnosticLevel {
|
||||
span: bug.span.primary_span().unwrap(),
|
||||
level: bug.level,
|
||||
};
|
||||
// FIXME: Cannot use `Diagnostic::subdiagnostic` which takes `DiagCtxt`, but it
|
||||
// just uses `DiagCtxtInner` functions.
|
||||
subdiag.add_to_diagnostic_with(&mut bug, |diag, msg| {
|
||||
let args = diag.args();
|
||||
let msg = diag.subdiagnostic_message_to_diagnostic_message(msg);
|
||||
self.eagerly_translate(msg, args)
|
||||
});
|
||||
//
|
||||
// We are at the `Diagnostic`/`DiagCtxtInner` level rather than
|
||||
// the usual `DiagnosticBuilder`/`DiagCtxt` level, so we must
|
||||
// augment `bug` in a lower-level fashion.
|
||||
bug.arg("level", bug.level);
|
||||
let msg = crate::fluent_generated::errors_invalid_flushed_delayed_diagnostic_level;
|
||||
let msg = self.eagerly_translate_for_subdiag(&bug, msg); // after the `arg` call
|
||||
bug.sub(Level::Note, msg, bug.span.primary_span().unwrap().into());
|
||||
}
|
||||
bug.level = Bug;
|
||||
|
||||
@ -1571,39 +1576,22 @@ impl DelayedDiagnostic {
|
||||
DelayedDiagnostic { inner: diagnostic, note: backtrace }
|
||||
}
|
||||
|
||||
fn decorate(mut self, dcx: &DiagCtxtInner) -> Diagnostic {
|
||||
// FIXME: Cannot use `Diagnostic::subdiagnostic` which takes `DiagCtxt`, but it
|
||||
// just uses `DiagCtxtInner` functions.
|
||||
let subdiag_with = |diag: &mut Diagnostic, msg| {
|
||||
let args = diag.args();
|
||||
let msg = diag.subdiagnostic_message_to_diagnostic_message(msg);
|
||||
dcx.eagerly_translate(msg, args)
|
||||
};
|
||||
|
||||
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);
|
||||
}
|
||||
fn decorate(self, dcx: &DiagCtxtInner) -> Diagnostic {
|
||||
// We are at the `Diagnostic`/`DiagCtxtInner` level rather than the
|
||||
// usual `DiagnosticBuilder`/`DiagCtxt` level, so we must construct
|
||||
// `diag` in a lower-level fashion.
|
||||
let mut diag = self.inner;
|
||||
let msg = match self.note.status() {
|
||||
BacktraceStatus::Captured => crate::fluent_generated::errors_delayed_at_with_newline,
|
||||
// Avoid the needless newline when no backtrace has been captured,
|
||||
// the display impl should just be a single line.
|
||||
_ => {
|
||||
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,
|
||||
_ => crate::fluent_generated::errors_delayed_at_without_newline,
|
||||
};
|
||||
subdiag.add_to_diagnostic_with(&mut self.inner, subdiag_with);
|
||||
}
|
||||
}
|
||||
|
||||
self.inner
|
||||
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());
|
||||
diag
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1176,6 +1176,8 @@ impl<'a> ExtCtxt<'a> {
|
||||
for (span, notes) in self.expansions.iter() {
|
||||
let mut db = self.dcx().create_note(errors::TraceMacro { span: *span });
|
||||
for note in notes {
|
||||
// FIXME: make this translatable
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
db.note(note.clone());
|
||||
}
|
||||
db.emit();
|
||||
|
@ -384,6 +384,7 @@ impl<'a> StripUnconfigured<'a> {
|
||||
);
|
||||
|
||||
if attr.is_doc_comment() {
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
err.help("`///` is for documentation comments. For a plain comment, use `//`.");
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ use rustc_ast::util::literal::escape_byte_str_symbol;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
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::parse_stream_from_source_str;
|
||||
use rustc_session::parse::ParseSess;
|
||||
@ -509,13 +509,14 @@ impl server::FreeFunctions for Rustc<'_, '_> {
|
||||
}
|
||||
|
||||
fn emit_diagnostic(&mut self, diagnostic: Diagnostic<Self::Span>) {
|
||||
let mut diag =
|
||||
rustc_errors::Diagnostic::new(diagnostic.level.to_internal(), diagnostic.message);
|
||||
let message = rustc_errors::DiagnosticMessage::from(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));
|
||||
for child in diagnostic.children {
|
||||
diag.sub(child.level.to_internal(), child.message, MultiSpan::from_spans(child.spans));
|
||||
}
|
||||
self.sess().dcx.emit_diagnostic(diag);
|
||||
diag.emit();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,8 @@ use std::borrow::Cow;
|
||||
|
||||
use crate::fluent_generated as fluent;
|
||||
use rustc_errors::{
|
||||
codes::*, AddToDiagnostic, Applicability, Diagnostic, DiagnosticArgValue, IntoDiagnosticArg,
|
||||
MultiSpan, SubdiagnosticMessageOp,
|
||||
codes::*, AddToDiagnostic, Applicability, DiagnosticArgValue, DiagnosticBuilder,
|
||||
EmissionGuarantee, IntoDiagnosticArg, MultiSpan, SubdiagnosticMessageOp,
|
||||
};
|
||||
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||
use rustc_middle::ty::Ty;
|
||||
@ -195,7 +195,11 @@ pub struct 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"));
|
||||
|
||||
// Only explain that `a ..b` is a range if it's split up
|
||||
@ -370,7 +374,11 @@ pub struct 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();
|
||||
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);
|
||||
@ -541,8 +549,12 @@ pub enum CastUnknownPointerSub {
|
||||
From(Span),
|
||||
}
|
||||
|
||||
impl AddToDiagnostic for CastUnknownPointerSub {
|
||||
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, f: F) {
|
||||
impl rustc_errors::AddToDiagnostic for CastUnknownPointerSub {
|
||||
fn add_to_diagnostic_with<G: EmissionGuarantee, F: SubdiagnosticMessageOp<G>>(
|
||||
self,
|
||||
diag: &mut DiagnosticBuilder<'_, G>,
|
||||
f: F,
|
||||
) {
|
||||
match self {
|
||||
CastUnknownPointerSub::To(span) => {
|
||||
let msg = f(diag, crate::fluent_generated::hir_typeck_label_to);
|
||||
|
@ -1,7 +1,8 @@
|
||||
use hir::GenericParamKind;
|
||||
use rustc_errors::{
|
||||
codes::*, AddToDiagnostic, Applicability, Diagnostic, DiagnosticMessage,
|
||||
DiagnosticStyledString, IntoDiagnosticArg, MultiSpan, SubdiagnosticMessageOp,
|
||||
codes::*, AddToDiagnostic, Applicability, DiagnosticBuilder, DiagnosticMessage,
|
||||
DiagnosticStyledString, EmissionGuarantee, IntoDiagnosticArg, MultiSpan,
|
||||
SubdiagnosticMessageOp,
|
||||
};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::FnRetTy;
|
||||
@ -225,7 +226,11 @@ pub enum RegionOriginNote<'a> {
|
||||
}
|
||||
|
||||
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 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 {
|
||||
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 {
|
||||
LifetimeMismatchLabels::InRet { param_span, ret_span, span, label_var1 } => {
|
||||
diag.span_label(param_span, fluent::infer_declared_different);
|
||||
@ -330,7 +339,11 @@ pub struct AddLifetimeParamsSuggestion<'a> {
|
||||
}
|
||||
|
||||
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 (
|
||||
hir::Ty { kind: hir::TyKind::Ref(lifetime_sub, _), .. },
|
||||
@ -428,7 +441,11 @@ pub struct 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
|
||||
.push_span_label(self.binding_span, fluent::infer_msl_introduces_static);
|
||||
diag.span_note(self.unmet_requirements, fluent::infer_msl_unmet_req);
|
||||
@ -743,7 +760,11 @@ pub struct 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();
|
||||
for &span in &self.spans {
|
||||
// Seems like we can't call f() here as Into<DiagnosticMessage> is required
|
||||
@ -784,7 +805,11 @@ pub struct 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();
|
||||
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);
|
||||
@ -827,7 +852,11 @@ pub struct 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 {
|
||||
self.span.push_span_label(sp, fluent::infer_ril_introduced_here);
|
||||
}
|
||||
@ -846,7 +875,11 @@ pub struct 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.primary_message(fluent::infer_more_targeted);
|
||||
diag.arg("ident", self.ident);
|
||||
@ -1265,7 +1298,11 @@ pub struct 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);
|
||||
let message = f(diag, crate::fluent_generated::infer_stp_wrap_many.into());
|
||||
diag.multipart_suggestions(
|
||||
|
@ -1,6 +1,9 @@
|
||||
use crate::fluent_generated as fluent;
|
||||
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_span::{symbol::kw, Span};
|
||||
|
||||
@ -160,7 +163,11 @@ impl 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("suff_kind", self.suffix);
|
||||
diag.arg("desc_kind", self.desc.kind);
|
||||
|
@ -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_errors::{add_elided_lifetime_in_path_suggestion, DiagnosticBuilder};
|
||||
use rustc_errors::{Applicability, SuggestionStyle};
|
||||
|
@ -1,5 +1,7 @@
|
||||
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_session::lint::Level;
|
||||
use rustc_span::{Span, Symbol};
|
||||
@ -24,7 +26,11 @@ pub enum 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 {
|
||||
OverruledAttributeSub::DefaultSource { id } => {
|
||||
diag.note(fluent::lint_default_source);
|
||||
|
@ -1062,6 +1062,9 @@ impl<'s, P: LintLevelsProvider> LintLevelsBuilder<'s, P> {
|
||||
if self.lint_added_lints {
|
||||
let lint = 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(
|
||||
self.sess,
|
||||
lint,
|
||||
|
@ -5,8 +5,8 @@ use std::num::NonZero;
|
||||
use crate::errors::RequestedLevel;
|
||||
use crate::fluent_generated as fluent;
|
||||
use rustc_errors::{
|
||||
codes::*, AddToDiagnostic, Applicability, DecorateLint, Diagnostic, DiagnosticBuilder,
|
||||
DiagnosticMessage, DiagnosticStyledString, SubdiagnosticMessageOp, SuggestionStyle,
|
||||
codes::*, AddToDiagnostic, Applicability, DecorateLint, DiagnosticBuilder, DiagnosticMessage,
|
||||
DiagnosticStyledString, EmissionGuarantee, SubdiagnosticMessageOp, SuggestionStyle,
|
||||
};
|
||||
use rustc_hir::def_id::DefId;
|
||||
use rustc_macros::{LintDiagnostic, Subdiagnostic};
|
||||
@ -267,17 +267,21 @@ pub struct SuggestChangingAssocTypes<'a, 'b> {
|
||||
pub ty: &'a rustc_hir::Ty<'b>,
|
||||
}
|
||||
|
||||
impl AddToDiagnostic for SuggestChangingAssocTypes<'_, '_> {
|
||||
fn add_to_diagnostic_with<F: SubdiagnosticMessageOp>(self, diag: &mut Diagnostic, _: F) {
|
||||
impl<'a, 'b> AddToDiagnostic for SuggestChangingAssocTypes<'a, 'b> {
|
||||
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
|
||||
// bound. Let's see if this type does that.
|
||||
|
||||
// We use a HIR visitor to walk the type.
|
||||
use rustc_hir::intravisit::{self, Visitor};
|
||||
struct WalkAssocTypes<'a> {
|
||||
err: &'a mut Diagnostic,
|
||||
struct WalkAssocTypes<'a, 'b, G: EmissionGuarantee> {
|
||||
err: &'a mut DiagnosticBuilder<'b, G>,
|
||||
}
|
||||
impl Visitor<'_> for WalkAssocTypes<'_> {
|
||||
impl<'a, 'b, G: EmissionGuarantee> Visitor<'_> for WalkAssocTypes<'a, 'b, G> {
|
||||
fn visit_qpath(
|
||||
&mut self,
|
||||
qpath: &rustc_hir::QPath<'_>,
|
||||
@ -320,7 +324,11 @@ pub struct 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(
|
||||
fluent::lint_suggestion,
|
||||
self.suggestions,
|
||||
@ -437,7 +445,11 @@ pub struct 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;
|
||||
loop {
|
||||
if let Some(span) = err.span {
|
||||
@ -488,7 +500,11 @@ pub struct BuiltinClashingExternSub<'a> {
|
||||
}
|
||||
|
||||
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();
|
||||
expected_str.push(self.expected.fn_sig(self.tcx).to_string(), false);
|
||||
let mut found_str = DiagnosticStyledString::new();
|
||||
@ -766,7 +782,11 @@ pub struct 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 {
|
||||
diag.span_label(span, format!("{c:?}"));
|
||||
}
|
||||
@ -780,7 +800,11 @@ pub enum HiddenUnicodeCodepointsDiagSub {
|
||||
|
||||
// Used because of multiple multipart_suggestion and note
|
||||
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 {
|
||||
HiddenUnicodeCodepointsDiagSub::Escape { spans } => {
|
||||
diag.multipart_suggestion_with_style(
|
||||
@ -928,7 +952,11 @@ pub struct 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;
|
||||
|
||||
if can_suggest_binding {
|
||||
@ -1208,7 +1236,11 @@ pub enum 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 {
|
||||
NonSnakeCaseDiagSub::Label { span } => {
|
||||
diag.span_label(span, fluent::lint_label);
|
||||
@ -1401,7 +1433,11 @@ pub enum 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 {
|
||||
OverflowingBinHexSign::Positive => {
|
||||
diag.note(fluent::lint_positive_note);
|
||||
|
@ -87,9 +87,13 @@ impl SubdiagnosticDeriveBuilder {
|
||||
let f = &self.f;
|
||||
let ret = structure.gen_impl(quote! {
|
||||
gen impl rustc_errors::AddToDiagnostic for @Self {
|
||||
fn add_to_diagnostic_with<__F>(self, #diag: &mut rustc_errors::Diagnostic, #f: __F)
|
||||
where
|
||||
__F: rustc_errors::SubdiagnosticMessageOp,
|
||||
fn add_to_diagnostic_with<__G, __F>(
|
||||
self,
|
||||
#diag: &mut rustc_errors::DiagnosticBuilder<'_, __G>,
|
||||
#f: __F
|
||||
) where
|
||||
__G: rustc_errors::EmissionGuarantee,
|
||||
__F: rustc_errors::SubdiagnosticMessageOp<__G>,
|
||||
{
|
||||
#implementation
|
||||
}
|
||||
|
@ -505,6 +505,8 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for MultipleCandidates {
|
||||
diag.code(E0464);
|
||||
diag.span(self.span);
|
||||
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
|
||||
@ -601,6 +603,8 @@ impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for InvalidMetadataFiles {
|
||||
diag.code(E0786);
|
||||
diag.span(self.span);
|
||||
for crate_rejection in self.crate_rejections {
|
||||
// FIXME: make this translatable
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
diag.note(crate_rejection);
|
||||
}
|
||||
diag
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::fluent_generated as fluent;
|
||||
use rustc_errors::DiagnosticArgValue;
|
||||
use rustc_errors::{
|
||||
codes::*, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
|
||||
codes::*, AddToDiagnostic, Applicability, DiagCtxt, DiagnosticBuilder, EmissionGuarantee,
|
||||
IntoDiagnostic, Level, MultiSpan, SubdiagnosticMessageOp,
|
||||
};
|
||||
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||
@ -420,7 +420,11 @@ pub struct 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);
|
||||
let body_start = self.body_span.shrink_to_lo();
|
||||
let body_end = self.body_span.shrink_to_hi();
|
||||
@ -863,7 +867,11 @@ pub struct Variant {
|
||||
}
|
||||
|
||||
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);
|
||||
let mut spans = MultiSpan::from(self.adt_def_span);
|
||||
|
||||
|
@ -87,6 +87,9 @@ pub(crate) struct 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>) {
|
||||
use UnsafetyViolationDetails::*;
|
||||
match self.violation {
|
||||
|
@ -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,
|
||||
// or a label with a dynamic value in a hard-coded string, but I haven't figured out
|
||||
// how to combine the two. 😢
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
diag.span_label(span, format!("generic parameter `{name}` is unused"));
|
||||
}
|
||||
diag
|
||||
|
@ -3,7 +3,7 @@ use std::borrow::Cow;
|
||||
use rustc_ast::token::Token;
|
||||
use rustc_ast::{Path, Visibility};
|
||||
use rustc_errors::{
|
||||
codes::*, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
|
||||
codes::*, AddToDiagnostic, Applicability, DiagCtxt, DiagnosticBuilder, EmissionGuarantee,
|
||||
IntoDiagnostic, Level, SubdiagnosticMessageOp,
|
||||
};
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
@ -1475,7 +1475,11 @@ pub(crate) struct 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);
|
||||
let applicability = if self.machine_applicable {
|
||||
Applicability::MachineApplicable
|
||||
|
@ -156,9 +156,12 @@ impl<'tcx> CheckConstVisitor<'tcx> {
|
||||
// is a pretty narrow case, however.
|
||||
if tcx.sess.is_nightly_build() {
|
||||
for gate in missing_secondary {
|
||||
let note =
|
||||
format!("add `#![feature({gate})]` to the crate attributes to enable",);
|
||||
err.help(note);
|
||||
// FIXME: make this translatable
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
err.help(format!(
|
||||
"add `#![feature({gate})]` to the crate attributes to enable"
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,9 +6,8 @@ use std::{
|
||||
use crate::fluent_generated as fluent;
|
||||
use rustc_ast::Label;
|
||||
use rustc_errors::{
|
||||
codes::*, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
|
||||
DiagnosticSymbolList, EmissionGuarantee, IntoDiagnostic, Level, MultiSpan,
|
||||
SubdiagnosticMessageOp,
|
||||
codes::*, AddToDiagnostic, Applicability, DiagCtxt, DiagnosticBuilder, DiagnosticSymbolList,
|
||||
EmissionGuarantee, IntoDiagnostic, Level, MultiSpan, SubdiagnosticMessageOp,
|
||||
};
|
||||
use rustc_hir::{self as hir, ExprKind, Target};
|
||||
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
|
||||
@ -1754,7 +1753,11 @@ pub struct 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.multipart_suggestion(
|
||||
crate::fluent_generated::passes_string_interpolation_only_works,
|
||||
|
@ -1,4 +1,4 @@
|
||||
use rustc_errors::{AddToDiagnostic, Diagnostic, SubdiagnosticMessageOp};
|
||||
use rustc_errors::{AddToDiagnostic, DiagnosticBuilder, EmissionGuarantee, SubdiagnosticMessageOp};
|
||||
use rustc_macros::{LintDiagnostic, Subdiagnostic};
|
||||
use rustc_middle::thir::Pat;
|
||||
use rustc_middle::ty::Ty;
|
||||
@ -62,7 +62,11 @@ pub struct 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;
|
||||
|
||||
// FIXME(mejrs) unfortunately `#[derive(LintDiagnostic)]`
|
||||
|
@ -2468,6 +2468,9 @@ pub fn parse_externs(
|
||||
));
|
||||
let adjusted_name = name.replace('-', "_");
|
||||
if is_ascii_ident(&adjusted_name) {
|
||||
// FIXME: make this translatable
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
error.help(format!(
|
||||
"consider replacing the dashes with underscores: `{adjusted_name}`"
|
||||
));
|
||||
|
@ -1,7 +1,7 @@
|
||||
use crate::fluent_generated as fluent;
|
||||
use rustc_errors::{
|
||||
codes::*, AddToDiagnostic, Applicability, DiagCtxt, Diagnostic, DiagnosticBuilder,
|
||||
EmissionGuarantee, IntoDiagnostic, Level, SubdiagnosticMessageOp,
|
||||
codes::*, AddToDiagnostic, Applicability, DiagCtxt, DiagnosticBuilder, EmissionGuarantee,
|
||||
IntoDiagnostic, Level, SubdiagnosticMessageOp,
|
||||
};
|
||||
use rustc_macros::Diagnostic;
|
||||
use rustc_middle::ty::{self, ClosureKind, PolyTraitRef, Ty};
|
||||
@ -102,7 +102,11 @@ pub enum 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 {
|
||||
AdjustSignatureBorrow::Borrow { to_borrow } => {
|
||||
diag.arg("len", to_borrow.len());
|
||||
|
@ -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> {
|
||||
/// 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);
|
||||
}
|
||||
|
||||
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>(
|
||||
&mut self,
|
||||
cx: &T,
|
||||
|
@ -55,8 +55,11 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for TranslatableInIntoDiagn
|
||||
pub struct 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");
|
||||
//~^ ERROR diagnostics should be created using translatable messages
|
||||
}
|
||||
@ -65,7 +68,11 @@ impl AddToDiagnostic for UntranslatableInAddToDiagnostic {
|
||||
pub struct 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);
|
||||
}
|
||||
}
|
||||
|
@ -11,13 +11,13 @@ LL | #![deny(rustc::untranslatable_diagnostic)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: diagnostics should be created using translatable messages
|
||||
--> $DIR/diagnostics.rs:60:14
|
||||
--> $DIR/diagnostics.rs:63:14
|
||||
|
|
||||
LL | diag.note("untranslatable diagnostic");
|
||||
| ^^^^
|
||||
|
||||
error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls
|
||||
--> $DIR/diagnostics.rs:74:21
|
||||
--> $DIR/diagnostics.rs:81:21
|
||||
|
|
||||
LL | let _diag = dcx.struct_err(crate::fluent_generated::no_crate_example);
|
||||
| ^^^^^^^^^^
|
||||
@ -29,13 +29,13 @@ LL | #![deny(rustc::diagnostic_outside_of_impl)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: diagnostics should only be created in `IntoDiagnostic`/`AddToDiagnostic` impls
|
||||
--> $DIR/diagnostics.rs:77:21
|
||||
--> $DIR/diagnostics.rs:84:21
|
||||
|
|
||||
LL | let _diag = dcx.struct_err("untranslatable diagnostic");
|
||||
| ^^^^^^^^^^
|
||||
|
||||
error: diagnostics should be created using translatable messages
|
||||
--> $DIR/diagnostics.rs:77:21
|
||||
--> $DIR/diagnostics.rs:84:21
|
||||
|
|
||||
LL | let _diag = dcx.struct_err("untranslatable diagnostic");
|
||||
| ^^^^^^^^^^
|
||||
|
@ -8,9 +8,9 @@ LL | arg: NotIntoDiagnosticArg,
|
||||
| ^^^^^^^^^^^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `NotIntoDiagnosticArg`
|
||||
|
|
||||
= help: normalized in stderr
|
||||
note: required by a bound in `DiagnosticBuilder::<'a, G>::arg`
|
||||
--> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:LL:CC
|
||||
= note: this error originates in the macro `forward` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
note: required by a bound in `rustc_errors::diagnostic::<impl DiagnosticBuilder<'a, G>>::arg`
|
||||
--> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC
|
||||
= note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error[E0277]: the trait bound `NotIntoDiagnosticArg: IntoDiagnosticArg` is not satisfied
|
||||
--> $DIR/diagnostic-derive-doc-comment-field.rs:46:10
|
||||
@ -22,8 +22,9 @@ LL | arg: NotIntoDiagnosticArg,
|
||||
| ^^^^^^^^^^^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `NotIntoDiagnosticArg`
|
||||
|
|
||||
= help: normalized in stderr
|
||||
note: required by a bound in `Diagnostic::arg`
|
||||
note: required by a bound in `rustc_errors::diagnostic::<impl DiagnosticBuilder<'a, G>>::arg`
|
||||
--> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC
|
||||
= note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
// check-fail
|
||||
// Tests error conditions for specifying diagnostics using #[derive(Diagnostic)]
|
||||
|
||||
// normalize-stderr-test "the following other types implement trait `IntoDiagnosticArg`:(?:.*\n){0,9}\s+and \d+ others" -> "normalized in stderr"
|
||||
// normalize-stderr-test "diagnostic_builder\.rs:[0-9]+:[0-9]+" -> "diagnostic_builder.rs:LL:CC"
|
||||
// normalize-stderr-test "(COMPILER_DIR/.*\.rs):[0-9]+:[0-9]+" -> "$1:LL:CC"
|
||||
|
||||
// The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly,
|
||||
// changing the output of this test. Since Diagnostic is strictly internal to the compiler
|
||||
// the test is just ignored on stable and beta:
|
||||
|
@ -628,9 +628,9 @@ LL | other: Hello,
|
||||
| ^^^^^ the trait `IntoDiagnosticArg` is not implemented for `Hello`
|
||||
|
|
||||
= help: normalized in stderr
|
||||
note: required by a bound in `DiagnosticBuilder::<'a, G>::arg`
|
||||
--> $COMPILER_DIR/rustc_errors/src/diagnostic_builder.rs:LL:CC
|
||||
= note: this error originates in the macro `forward` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
note: required by a bound in `rustc_errors::diagnostic::<impl DiagnosticBuilder<'a, G>>::arg`
|
||||
--> $COMPILER_DIR/rustc_errors/src/diagnostic.rs:LL:CC
|
||||
= note: this error originates in the macro `with_fn` (in Nightly builds, run with -Z macro-backtrace for more info)
|
||||
|
||||
error: aborting due to 86 previous errors
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user