Rollup merge of #120571 - nnethercote:misc-diagnostics, r=oli-obk
Miscellaneous diagnostics cleanups All found while working on some speculative, invasive changes, but worth doing in their own right. r? `@oli-obk`
This commit is contained in:
commit
b9c87b41d3
@ -198,12 +198,12 @@ pub(crate) fn report_mutability_error(
|
||||
{
|
||||
let span = self.body.local_decls[local].source_info.span;
|
||||
mut_error = Some(span);
|
||||
if let Some((buffer, c)) = self.get_buffered_mut_error(span) {
|
||||
if let Some((buffered_err, c)) = self.get_buffered_mut_error(span) {
|
||||
// We've encountered a second (or more) attempt to mutably borrow an
|
||||
// immutable binding, so the likely problem is with the binding
|
||||
// declaration, not the use. We collect these in a single diagnostic
|
||||
// and make the binding the primary span of the error.
|
||||
err = buffer;
|
||||
err = buffered_err;
|
||||
count = c + 1;
|
||||
if count == 2 {
|
||||
err.replace_span_with(span, false);
|
||||
|
@ -102,7 +102,7 @@ pub(crate) struct DlltoolFailImportLibrary<'a> {
|
||||
impl<G: EmissionGuarantee> IntoDiagnostic<'_, G> for ParseTargetMachineConfig<'_> {
|
||||
fn into_diagnostic(self, dcx: &'_ DiagCtxt, level: Level) -> DiagnosticBuilder<'_, G> {
|
||||
let diag: DiagnosticBuilder<'_, G> = self.0.into_diagnostic(dcx, level);
|
||||
let (message, _) = diag.messages().first().expect("`LlvmError` with no message");
|
||||
let (message, _) = diag.messages.first().expect("`LlvmError` with no message");
|
||||
let message = dcx.eagerly_translate_to_string(message.clone(), diag.args());
|
||||
|
||||
DiagnosticBuilder::new(dcx, level, fluent::codegen_llvm_parse_target_machine_config)
|
||||
|
@ -39,7 +39,6 @@
|
||||
|
||||
use crate::errors::ErrorCreatingRemarkDir;
|
||||
use std::any::Any;
|
||||
use std::borrow::Cow;
|
||||
use std::fs;
|
||||
use std::io;
|
||||
use std::marker::PhantomData;
|
||||
@ -1812,12 +1811,12 @@ fn fallback_fluent_bundle(&self) -> &FluentBundle {
|
||||
|
||||
impl Emitter for SharedEmitter {
|
||||
fn emit_diagnostic(&mut self, diag: &rustc_errors::Diagnostic) {
|
||||
let args: FxHashMap<Cow<'_, str>, DiagnosticArgValue> =
|
||||
let args: FxHashMap<DiagnosticArgName, DiagnosticArgValue> =
|
||||
diag.args().map(|(name, arg)| (name.clone(), arg.clone())).collect();
|
||||
drop(self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic {
|
||||
msgs: diag.messages.clone(),
|
||||
args: args.clone(),
|
||||
code: diag.code.clone(),
|
||||
code: diag.code,
|
||||
lvl: diag.level(),
|
||||
})));
|
||||
for child in &diag.children {
|
||||
|
@ -1,6 +1,8 @@
|
||||
use std::mem;
|
||||
|
||||
use rustc_errors::{DiagnosticArgValue, DiagnosticMessage, IntoDiagnostic, IntoDiagnosticArg};
|
||||
use rustc_errors::{
|
||||
DiagnosticArgName, DiagnosticArgValue, DiagnosticMessage, IntoDiagnostic, IntoDiagnosticArg,
|
||||
};
|
||||
use rustc_hir::CRATE_HIR_ID;
|
||||
use rustc_middle::mir::AssertKind;
|
||||
use rustc_middle::query::TyCtxtAt;
|
||||
@ -32,10 +34,7 @@ fn diagnostic_message(&self) -> DiagnosticMessage {
|
||||
AssertFailure(x) => x.diagnostic_message(),
|
||||
}
|
||||
}
|
||||
fn add_args(
|
||||
self: Box<Self>,
|
||||
adder: &mut dyn FnMut(std::borrow::Cow<'static, str>, DiagnosticArgValue),
|
||||
) {
|
||||
fn add_args(self: Box<Self>, adder: &mut dyn FnMut(DiagnosticArgName, DiagnosticArgValue)) {
|
||||
use ConstEvalErrKind::*;
|
||||
match *self {
|
||||
ConstAccessesStatic | ModifiedGlobal => {}
|
||||
|
@ -33,7 +33,10 @@
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
|
||||
pub enum DiagnosticArgValue {
|
||||
Str(Cow<'static, str>),
|
||||
Number(i128),
|
||||
// This gets converted to a `FluentNumber`, which is an `f64`. An `i32`
|
||||
// safely fits in an `f64`. Any integers bigger than that will be converted
|
||||
// to strings in `into_diagnostic_arg` and stored using the `Str` variant.
|
||||
Number(i32),
|
||||
StrListSepByAnd(Vec<Cow<'static, str>>),
|
||||
}
|
||||
|
||||
@ -113,7 +116,7 @@ pub struct Diagnostic {
|
||||
|
||||
/// With `-Ztrack_diagnostics` enabled,
|
||||
/// we print where in rustc this error was emitted.
|
||||
pub emitted_at: DiagnosticLocation,
|
||||
pub(crate) emitted_at: DiagnosticLocation,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Encodable, Decodable)]
|
||||
@ -162,10 +165,10 @@ pub fn new() -> DiagnosticStyledString {
|
||||
DiagnosticStyledString(vec![])
|
||||
}
|
||||
pub fn push_normal<S: Into<String>>(&mut self, t: S) {
|
||||
self.0.push(StringPart::Normal(t.into()));
|
||||
self.0.push(StringPart::normal(t));
|
||||
}
|
||||
pub fn push_highlighted<S: Into<String>>(&mut self, t: S) {
|
||||
self.0.push(StringPart::Highlighted(t.into()));
|
||||
self.0.push(StringPart::highlighted(t));
|
||||
}
|
||||
pub fn push<S: Into<String>>(&mut self, t: S, highlight: bool) {
|
||||
if highlight {
|
||||
@ -175,35 +178,34 @@ pub fn push<S: Into<String>>(&mut self, t: S, highlight: bool) {
|
||||
}
|
||||
}
|
||||
pub fn normal<S: Into<String>>(t: S) -> DiagnosticStyledString {
|
||||
DiagnosticStyledString(vec![StringPart::Normal(t.into())])
|
||||
DiagnosticStyledString(vec![StringPart::normal(t)])
|
||||
}
|
||||
|
||||
pub fn highlighted<S: Into<String>>(t: S) -> DiagnosticStyledString {
|
||||
DiagnosticStyledString(vec![StringPart::Highlighted(t.into())])
|
||||
DiagnosticStyledString(vec![StringPart::highlighted(t)])
|
||||
}
|
||||
|
||||
pub fn content(&self) -> String {
|
||||
self.0.iter().map(|x| x.content()).collect::<String>()
|
||||
self.0.iter().map(|x| x.content.as_str()).collect::<String>()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum StringPart {
|
||||
Normal(String),
|
||||
Highlighted(String),
|
||||
pub struct StringPart {
|
||||
content: String,
|
||||
style: Style,
|
||||
}
|
||||
|
||||
impl StringPart {
|
||||
pub fn content(&self) -> &str {
|
||||
match self {
|
||||
&StringPart::Normal(ref s) | &StringPart::Highlighted(ref s) => s,
|
||||
}
|
||||
pub fn normal<S: Into<String>>(content: S) -> StringPart {
|
||||
StringPart { content: content.into(), style: Style::NoStyle }
|
||||
}
|
||||
|
||||
pub fn highlighted<S: Into<String>>(content: S) -> StringPart {
|
||||
StringPart { content: content.into(), style: Style::Highlight }
|
||||
}
|
||||
}
|
||||
|
||||
// Note: most of these methods are setters that return `&mut Self`. The small
|
||||
// number of simple getter functions all have `get_` prefixes to distinguish
|
||||
// them from the setters.
|
||||
impl Diagnostic {
|
||||
#[track_caller]
|
||||
pub fn new<M: Into<DiagnosticMessage>>(level: Level, message: M) -> Self {
|
||||
@ -389,19 +391,16 @@ pub fn note_expected_found_extra(
|
||||
} else {
|
||||
(0, found_label.len() - expected_label.len())
|
||||
};
|
||||
let mut msg: Vec<_> =
|
||||
vec![(format!("{}{} `", " ".repeat(expected_padding), expected_label), Style::NoStyle)];
|
||||
msg.extend(expected.0.iter().map(|x| match *x {
|
||||
StringPart::Normal(ref s) => (s.to_owned(), Style::NoStyle),
|
||||
StringPart::Highlighted(ref s) => (s.to_owned(), Style::Highlight),
|
||||
}));
|
||||
msg.push((format!("`{expected_extra}\n"), Style::NoStyle));
|
||||
msg.push((format!("{}{} `", " ".repeat(found_padding), found_label), Style::NoStyle));
|
||||
msg.extend(found.0.iter().map(|x| match *x {
|
||||
StringPart::Normal(ref s) => (s.to_owned(), Style::NoStyle),
|
||||
StringPart::Highlighted(ref s) => (s.to_owned(), Style::Highlight),
|
||||
}));
|
||||
msg.push((format!("`{found_extra}"), Style::NoStyle));
|
||||
let mut msg = vec![StringPart::normal(format!(
|
||||
"{}{} `",
|
||||
" ".repeat(expected_padding),
|
||||
expected_label
|
||||
))];
|
||||
msg.extend(expected.0.into_iter());
|
||||
msg.push(StringPart::normal(format!("`{expected_extra}\n")));
|
||||
msg.push(StringPart::normal(format!("{}{} `", " ".repeat(found_padding), found_label)));
|
||||
msg.extend(found.0.into_iter());
|
||||
msg.push(StringPart::normal(format!("`{found_extra}")));
|
||||
|
||||
// For now, just attach these as notes.
|
||||
self.highlighted_note(msg);
|
||||
@ -410,9 +409,9 @@ pub fn note_expected_found_extra(
|
||||
|
||||
pub fn note_trait_signature(&mut self, name: Symbol, signature: String) -> &mut Self {
|
||||
self.highlighted_note(vec![
|
||||
(format!("`{name}` from trait: `"), Style::NoStyle),
|
||||
(signature, Style::Highlight),
|
||||
("`".to_string(), Style::NoStyle),
|
||||
StringPart::normal(format!("`{name}` from trait: `")),
|
||||
StringPart::highlighted(signature),
|
||||
StringPart::normal("`"),
|
||||
]);
|
||||
self
|
||||
}
|
||||
@ -424,10 +423,7 @@ pub fn note(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self {
|
||||
self
|
||||
}
|
||||
|
||||
fn highlighted_note<M: Into<SubdiagnosticMessage>>(
|
||||
&mut self,
|
||||
msg: Vec<(M, Style)>,
|
||||
) -> &mut Self {
|
||||
fn highlighted_note(&mut self, msg: Vec<StringPart>) -> &mut Self {
|
||||
self.sub_with_highlights(Level::Note, msg, MultiSpan::new());
|
||||
self
|
||||
}
|
||||
@ -496,7 +492,7 @@ pub fn help_once(&mut self, msg: impl Into<SubdiagnosticMessage>) -> &mut Self {
|
||||
}
|
||||
|
||||
/// Add a help message attached to this diagnostic with a customizable highlighted message.
|
||||
pub fn highlighted_help(&mut self, msg: Vec<(String, Style)>) -> &mut Self {
|
||||
pub fn highlighted_help(&mut self, msg: Vec<StringPart>) -> &mut Self {
|
||||
self.sub_with_highlights(Level::Help, msg, MultiSpan::new());
|
||||
self
|
||||
}
|
||||
@ -890,15 +886,6 @@ pub fn code(&mut self, code: ErrCode) -> &mut Self {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn clear_code(&mut self) -> &mut Self {
|
||||
self.code = None;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn get_code(&self) -> Option<ErrCode> {
|
||||
self.code
|
||||
}
|
||||
|
||||
pub fn primary_message(&mut self, msg: impl Into<DiagnosticMessage>) -> &mut Self {
|
||||
self.messages[0] = (msg.into(), Style::NoStyle);
|
||||
self
|
||||
@ -913,7 +900,7 @@ pub fn args(&self) -> impl Iterator<Item = DiagnosticArg<'_>> {
|
||||
|
||||
pub fn arg(
|
||||
&mut self,
|
||||
name: impl Into<Cow<'static, str>>,
|
||||
name: impl Into<DiagnosticArgName>,
|
||||
arg: impl IntoDiagnosticArg,
|
||||
) -> &mut Self {
|
||||
self.args.insert(name.into(), arg.into_diagnostic_arg());
|
||||
@ -924,10 +911,6 @@ pub fn replace_args(&mut self, args: FxHashMap<DiagnosticArgName, DiagnosticArgV
|
||||
self.args = args;
|
||||
}
|
||||
|
||||
pub fn messages(&self) -> &[(DiagnosticMessage, Style)] {
|
||||
&self.messages
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// passes the user's string along).
|
||||
@ -958,15 +941,10 @@ pub fn sub(&mut self, level: Level, message: impl Into<SubdiagnosticMessage>, sp
|
||||
|
||||
/// Convenience function for internal use, clients should use one of the
|
||||
/// public methods above.
|
||||
fn sub_with_highlights<M: Into<SubdiagnosticMessage>>(
|
||||
&mut self,
|
||||
level: Level,
|
||||
messages: Vec<(M, Style)>,
|
||||
span: MultiSpan,
|
||||
) {
|
||||
fn sub_with_highlights(&mut self, level: Level, messages: Vec<StringPart>, span: MultiSpan) {
|
||||
let messages = messages
|
||||
.into_iter()
|
||||
.map(|m| (self.subdiagnostic_message_to_diagnostic_message(m.0), m.1))
|
||||
.map(|m| (self.subdiagnostic_message_to_diagnostic_message(m.content), m.style))
|
||||
.collect();
|
||||
let sub = SubDiagnostic { level, messages, span };
|
||||
self.children.push(sub);
|
||||
|
@ -63,12 +63,8 @@ macro_rules! into_diagnostic_arg_for_number {
|
||||
$(
|
||||
impl IntoDiagnosticArg for $ty {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue {
|
||||
// HACK: `FluentNumber` the underline backing struct represent
|
||||
// numbers using a f64 which can't represent all the i128 numbers
|
||||
// So in order to be able to use fluent selectors and still
|
||||
// have all the numbers representable we only convert numbers
|
||||
// below a certain threshold.
|
||||
if let Ok(n) = TryInto::<i128>::try_into(self) && n >= -100 && n <= 100 {
|
||||
// Convert to a string if it won't fit into `Number`.
|
||||
if let Ok(n) = TryInto::<i32>::try_into(self) {
|
||||
DiagnosticArgValue::Number(n)
|
||||
} else {
|
||||
self.to_string().into_diagnostic_arg()
|
||||
|
@ -558,7 +558,7 @@ fn supports_color(&self) -> bool {
|
||||
/// failures of rustc, as witnessed e.g. in issue #89358.
|
||||
pub struct SilentEmitter {
|
||||
pub fatal_dcx: DiagCtxt,
|
||||
pub fatal_note: Option<String>,
|
||||
pub fatal_note: String,
|
||||
}
|
||||
|
||||
impl Translate for SilentEmitter {
|
||||
@ -576,13 +576,11 @@ fn source_map(&self) -> Option<&Lrc<SourceMap>> {
|
||||
None
|
||||
}
|
||||
|
||||
fn emit_diagnostic(&mut self, d: &Diagnostic) {
|
||||
if d.level == Level::Fatal {
|
||||
let mut d = d.clone();
|
||||
if let Some(ref note) = self.fatal_note {
|
||||
d.note(note.clone());
|
||||
}
|
||||
self.fatal_dcx.emit_diagnostic(d);
|
||||
fn emit_diagnostic(&mut self, diag: &Diagnostic) {
|
||||
if diag.level == Level::Fatal {
|
||||
let mut diag = diag.clone();
|
||||
diag.note(self.fatal_note.clone());
|
||||
self.fatal_dcx.emit_diagnostic(diag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -34,7 +34,7 @@
|
||||
pub use codes::*;
|
||||
pub use diagnostic::{
|
||||
AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgName,
|
||||
DiagnosticArgValue, DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
|
||||
DiagnosticArgValue, DiagnosticStyledString, IntoDiagnosticArg, StringPart, SubDiagnostic,
|
||||
};
|
||||
pub use diagnostic_builder::{
|
||||
BugAbort, DiagnosticBuilder, EmissionGuarantee, FatalAbort, IntoDiagnostic,
|
||||
@ -102,7 +102,6 @@
|
||||
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
|
||||
|
||||
// `PResult` is used a lot. Make sure it doesn't unintentionally get bigger.
|
||||
// (See also the comment on `DiagnosticBuilderInner`'s `diagnostic` field.)
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
rustc_data_structures::static_assert_size!(PResult<'_, ()>, 16);
|
||||
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
|
||||
@ -1039,10 +1038,6 @@ pub fn print_error_count(&self, registry: &Registry) {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn take_future_breakage_diagnostics(&self) -> Vec<Diagnostic> {
|
||||
std::mem::take(&mut self.inner.borrow_mut().future_breakage_diagnostics)
|
||||
}
|
||||
|
||||
pub fn abort_if_errors(&self) {
|
||||
let mut inner = self.inner.borrow_mut();
|
||||
inner.emit_stashed_diagnostics();
|
||||
@ -1150,8 +1145,12 @@ pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) {
|
||||
self.inner.borrow_mut().emitter.emit_artifact_notification(path, artifact_type);
|
||||
}
|
||||
|
||||
pub fn emit_future_breakage_report(&self, diags: Vec<Diagnostic>) {
|
||||
self.inner.borrow_mut().emitter.emit_future_breakage_report(diags)
|
||||
pub fn emit_future_breakage_report(&self) {
|
||||
let mut inner = self.inner.borrow_mut();
|
||||
let diags = std::mem::take(&mut inner.future_breakage_diagnostics);
|
||||
if !diags.is_empty() {
|
||||
inner.emitter.emit_future_breakage_report(diags);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn emit_unused_externs(
|
||||
@ -1224,9 +1223,8 @@ impl DiagCtxtInner {
|
||||
/// Emit all stashed diagnostics.
|
||||
fn emit_stashed_diagnostics(&mut self) -> Option<ErrorGuaranteed> {
|
||||
let has_errors = self.has_errors();
|
||||
let diags = self.stashed_diagnostics.drain(..).map(|x| x.1).collect::<Vec<_>>();
|
||||
let mut reported = None;
|
||||
for diag in diags {
|
||||
for (_, diag) in std::mem::take(&mut self.stashed_diagnostics).into_iter() {
|
||||
// Decrement the count tracking the stash; emitting will increment it.
|
||||
if diag.is_error() {
|
||||
if diag.is_lint.is_some() {
|
||||
@ -1254,7 +1252,7 @@ fn emit_diagnostic(&mut self, mut diagnostic: Diagnostic) -> Option<ErrorGuarant
|
||||
// be stored. Instead, they are buffered until the `LintExpectationId` is replaced by
|
||||
// a stable one by the `LintLevelsBuilder`.
|
||||
if let Some(LintExpectationId::Unstable { .. }) = diagnostic.level.get_expectation_id() {
|
||||
self.unstable_expect_diagnostics.push(diagnostic.clone());
|
||||
self.unstable_expect_diagnostics.push(diagnostic);
|
||||
return None;
|
||||
}
|
||||
|
||||
@ -1269,16 +1267,14 @@ fn emit_diagnostic(&mut self, mut diagnostic: Diagnostic) -> Option<ErrorGuarant
|
||||
DelayedBug(DelayedBugKind::Normal) => {
|
||||
let backtrace = std::backtrace::Backtrace::capture();
|
||||
self.span_delayed_bugs
|
||||
.push(DelayedDiagnostic::with_backtrace(diagnostic.clone(), backtrace));
|
||||
|
||||
.push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace));
|
||||
#[allow(deprecated)]
|
||||
return Some(ErrorGuaranteed::unchecked_claim_error_was_emitted());
|
||||
}
|
||||
DelayedBug(DelayedBugKind::GoodPath) => {
|
||||
let backtrace = std::backtrace::Backtrace::capture();
|
||||
self.good_path_delayed_bugs
|
||||
.push(DelayedDiagnostic::with_backtrace(diagnostic.clone(), backtrace));
|
||||
|
||||
.push(DelayedDiagnostic::with_backtrace(diagnostic, backtrace));
|
||||
return None;
|
||||
}
|
||||
_ => {}
|
||||
@ -1424,7 +1420,7 @@ fn flush_delayed(&mut self, kind: DelayedBugKind) {
|
||||
&mut out,
|
||||
"delayed span bug: {}\n{}\n",
|
||||
bug.inner
|
||||
.messages()
|
||||
.messages
|
||||
.iter()
|
||||
.filter_map(|(msg, _)| msg.as_str())
|
||||
.collect::<String>(),
|
||||
|
@ -197,7 +197,7 @@ pub struct StyledString {
|
||||
pub style: Style,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
|
||||
pub enum Style {
|
||||
MainHeaderMsg,
|
||||
HeaderMsg,
|
||||
|
@ -590,7 +590,6 @@ fn infer_placeholder_type<'a>(
|
||||
|
||||
// The parser provided a sub-optimal `HasPlaceholders` suggestion for the type.
|
||||
// We are typeck and have the real type, so remove that and suggest the actual type.
|
||||
// FIXME(eddyb) this looks like it should be functionality on `Diagnostic`.
|
||||
if let Ok(suggestions) = &mut err.suggestions {
|
||||
suggestions.clear();
|
||||
}
|
||||
|
@ -576,7 +576,7 @@ fn emit_err_pat_range(
|
||||
if (lhs, rhs).references_error() {
|
||||
err.downgrade_to_delayed_bug();
|
||||
}
|
||||
if self.tcx.sess.teach(err.get_code().unwrap()) {
|
||||
if self.tcx.sess.teach(err.code.unwrap()) {
|
||||
err.note(
|
||||
"In a match expression, only numbers and characters can be matched \
|
||||
against a range. This is because the compiler checks that the range \
|
||||
@ -847,7 +847,7 @@ pub fn check_dereferenceable(
|
||||
type_str
|
||||
);
|
||||
err.span_label(span, format!("type `{type_str}` cannot be dereferenced"));
|
||||
if self.tcx.sess.teach(err.get_code().unwrap()) {
|
||||
if self.tcx.sess.teach(err.code.unwrap()) {
|
||||
err.note(CANNOT_IMPLICITLY_DEREF_POINTER_TRAIT_OBJ);
|
||||
}
|
||||
return Err(err.emit());
|
||||
@ -1669,7 +1669,7 @@ fn error_inexistent_fields(
|
||||
}
|
||||
}
|
||||
}
|
||||
if tcx.sess.teach(err.get_code().unwrap()) {
|
||||
if tcx.sess.teach(err.code.unwrap()) {
|
||||
err.note(
|
||||
"This error indicates that a struct pattern attempted to \
|
||||
extract a nonexistent field from a struct. Struct fields \
|
||||
|
@ -195,7 +195,7 @@ pub fn note_and_explain_type_err(
|
||||
}
|
||||
}
|
||||
diag.help("type parameters must be constrained to match other types");
|
||||
if tcx.sess.teach(diag.get_code().unwrap()) {
|
||||
if tcx.sess.teach(diag.code.unwrap()) {
|
||||
diag.help(
|
||||
"given a type parameter `T` and a method `foo`:
|
||||
```
|
||||
@ -678,7 +678,7 @@ fn expected_projection(
|
||||
https://doc.rust-lang.org/book/ch19-03-advanced-traits.html",
|
||||
);
|
||||
}
|
||||
if tcx.sess.teach(diag.get_code().unwrap()) {
|
||||
if tcx.sess.teach(diag.code.unwrap()) {
|
||||
diag.help(
|
||||
"given an associated type `T` and a method `foo`:
|
||||
```
|
||||
|
@ -45,20 +45,19 @@ pub struct Compiler {
|
||||
pub(crate) fn parse_cfg(dcx: &DiagCtxt, cfgs: Vec<String>) -> Cfg {
|
||||
cfgs.into_iter()
|
||||
.map(|s| {
|
||||
let sess = ParseSess::with_silent_emitter(Some(format!(
|
||||
let sess = ParseSess::with_silent_emitter(format!(
|
||||
"this error occurred on the command line: `--cfg={s}`"
|
||||
)));
|
||||
));
|
||||
let filename = FileName::cfg_spec_source_code(&s);
|
||||
|
||||
macro_rules! error {
|
||||
($reason: expr) => {
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
dcx.struct_fatal(format!(
|
||||
dcx.fatal(format!(
|
||||
concat!("invalid `--cfg` argument: `{}` (", $reason, ")"),
|
||||
s
|
||||
))
|
||||
.emit();
|
||||
));
|
||||
};
|
||||
}
|
||||
|
||||
@ -108,20 +107,19 @@ pub(crate) fn parse_check_cfg(dcx: &DiagCtxt, specs: Vec<String>) -> CheckCfg {
|
||||
let mut check_cfg = CheckCfg { exhaustive_names, exhaustive_values, ..CheckCfg::default() };
|
||||
|
||||
for s in specs {
|
||||
let sess = ParseSess::with_silent_emitter(Some(format!(
|
||||
let sess = ParseSess::with_silent_emitter(format!(
|
||||
"this error occurred on the command line: `--check-cfg={s}`"
|
||||
)));
|
||||
));
|
||||
let filename = FileName::cfg_spec_source_code(&s);
|
||||
|
||||
macro_rules! error {
|
||||
($reason:expr) => {
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
dcx.struct_fatal(format!(
|
||||
dcx.fatal(format!(
|
||||
concat!("invalid `--check-cfg` argument: `{}` (", $reason, ")"),
|
||||
s
|
||||
))
|
||||
.emit()
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
|
||||
use rustc_errors::{codes::*, DiagnosticArgValue, DiagnosticMessage};
|
||||
use rustc_errors::{codes::*, DiagnosticArgName, DiagnosticArgValue, DiagnosticMessage};
|
||||
use rustc_macros::Diagnostic;
|
||||
use rustc_span::{Span, Symbol};
|
||||
|
||||
@ -95,14 +94,14 @@ pub(super) struct ConstNotUsedTraitAlias {
|
||||
|
||||
pub struct CustomSubdiagnostic<'a> {
|
||||
pub msg: fn() -> DiagnosticMessage,
|
||||
pub add_args: Box<dyn FnOnce(&mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue)) + 'a>,
|
||||
pub add_args: Box<dyn FnOnce(&mut dyn FnMut(DiagnosticArgName, DiagnosticArgValue)) + 'a>,
|
||||
}
|
||||
|
||||
impl<'a> CustomSubdiagnostic<'a> {
|
||||
pub fn label(x: fn() -> DiagnosticMessage) -> Self {
|
||||
Self::label_and_then(x, |_| {})
|
||||
}
|
||||
pub fn label_and_then<F: FnOnce(&mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue)) + 'a>(
|
||||
pub fn label_and_then<F: FnOnce(&mut dyn FnMut(DiagnosticArgName, DiagnosticArgValue)) + 'a>(
|
||||
msg: fn() -> DiagnosticMessage,
|
||||
f: F,
|
||||
) -> Self {
|
||||
|
@ -5,7 +5,9 @@
|
||||
use crate::ty::{layout, tls, Ty, TyCtxt, ValTree};
|
||||
|
||||
use rustc_data_structures::sync::Lock;
|
||||
use rustc_errors::{DiagnosticArgValue, DiagnosticMessage, ErrorGuaranteed, IntoDiagnosticArg};
|
||||
use rustc_errors::{
|
||||
DiagnosticArgName, DiagnosticArgValue, DiagnosticMessage, ErrorGuaranteed, IntoDiagnosticArg,
|
||||
};
|
||||
use rustc_macros::HashStable;
|
||||
use rustc_session::CtfeBacktrace;
|
||||
use rustc_span::{def_id::DefId, Span, DUMMY_SP};
|
||||
@ -485,7 +487,7 @@ pub trait MachineStopType: Any + fmt::Debug + Send {
|
||||
fn diagnostic_message(&self) -> DiagnosticMessage;
|
||||
/// Add diagnostic arguments by passing name and value pairs to `adder`, which are passed to
|
||||
/// fluent for formatting the translated diagnostic message.
|
||||
fn add_args(self: Box<Self>, adder: &mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue));
|
||||
fn add_args(self: Box<Self>, adder: &mut dyn FnMut(DiagnosticArgName, DiagnosticArgValue));
|
||||
}
|
||||
|
||||
impl dyn MachineStopType {
|
||||
|
@ -14,7 +14,9 @@
|
||||
use crate::ty::{GenericArg, GenericArgsRef};
|
||||
|
||||
use rustc_data_structures::captures::Captures;
|
||||
use rustc_errors::{DiagnosticArgValue, DiagnosticMessage, ErrorGuaranteed, IntoDiagnosticArg};
|
||||
use rustc_errors::{
|
||||
DiagnosticArgName, DiagnosticArgValue, DiagnosticMessage, ErrorGuaranteed, IntoDiagnosticArg,
|
||||
};
|
||||
use rustc_hir::def::{CtorKind, Namespace};
|
||||
use rustc_hir::def_id::{DefId, CRATE_DEF_ID};
|
||||
use rustc_hir::{self, CoroutineDesugaring, CoroutineKind, ImplicitSelfKind};
|
||||
|
@ -292,7 +292,7 @@ pub fn diagnostic_message(&self) -> DiagnosticMessage {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_args(self, adder: &mut dyn FnMut(Cow<'static, str>, DiagnosticArgValue))
|
||||
pub fn add_args(self, adder: &mut dyn FnMut(DiagnosticArgName, DiagnosticArgValue))
|
||||
where
|
||||
O: fmt::Debug,
|
||||
{
|
||||
|
@ -34,7 +34,7 @@ fn diagnostic_message(&self) -> rustc_errors::DiagnosticMessage {
|
||||
|
||||
fn add_args(
|
||||
self: Box<Self>,
|
||||
_: &mut dyn FnMut(std::borrow::Cow<'static, str>, rustc_errors::DiagnosticArgValue),
|
||||
_: &mut dyn FnMut(rustc_errors::DiagnosticArgName, rustc_errors::DiagnosticArgValue),
|
||||
) {}
|
||||
}
|
||||
throw_machine_stop!(Zst)
|
||||
|
@ -39,7 +39,7 @@
|
||||
// uses a HOF to parse anything, and <source> includes file and
|
||||
// `source_str`.
|
||||
|
||||
/// A variant of 'panictry!' that works on a `Vec<Diagnostic>` instead of a single
|
||||
/// A variant of 'panictry!' that works on a `Vec<DiagnosticBuilder>` instead of a single
|
||||
/// `DiagnosticBuilder`.
|
||||
macro_rules! panictry_buffer {
|
||||
($e:expr) => {{
|
||||
|
@ -258,7 +258,7 @@ pub fn with_dcx(dcx: DiagCtxt, source_map: Lrc<SourceMap>) -> Self {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_silent_emitter(fatal_note: Option<String>) -> Self {
|
||||
pub fn with_silent_emitter(fatal_note: String) -> Self {
|
||||
let fallback_bundle = fallback_fluent_bundle(Vec::new(), false);
|
||||
let sm = Lrc::new(SourceMap::new(FilePathMapping::empty()));
|
||||
let fatal_dcx = DiagCtxt::with_tty_emitter(None, fallback_bundle).disable_warnings();
|
||||
|
@ -288,19 +288,9 @@ fn check_miri_unleashed_features(&self) {
|
||||
pub fn finish_diagnostics(&self, registry: &Registry) {
|
||||
self.check_miri_unleashed_features();
|
||||
self.dcx().print_error_count(registry);
|
||||
self.emit_future_breakage();
|
||||
}
|
||||
|
||||
fn emit_future_breakage(&self) {
|
||||
if !self.opts.json_future_incompat {
|
||||
return;
|
||||
if self.opts.json_future_incompat {
|
||||
self.dcx().emit_future_breakage_report();
|
||||
}
|
||||
|
||||
let diags = self.dcx().take_future_breakage_diagnostics();
|
||||
if diags.is_empty() {
|
||||
return;
|
||||
}
|
||||
self.dcx().emit_future_breakage_report(diags);
|
||||
}
|
||||
|
||||
/// Returns true if the crate is a testing one.
|
||||
|
@ -2717,7 +2717,7 @@ fn note_obligation_cause_for_async_await(
|
||||
let (trait_name, trait_verb) =
|
||||
if name == sym::Send { ("`Send`", "sent") } else { ("`Sync`", "shared") };
|
||||
|
||||
err.clear_code();
|
||||
err.code = None;
|
||||
err.primary_message(format!(
|
||||
"{future_or_coroutine} cannot be {trait_verb} between threads safely"
|
||||
));
|
||||
|
@ -20,7 +20,7 @@
|
||||
use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
|
||||
use rustc_errors::{
|
||||
codes::*, pluralize, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder,
|
||||
ErrorGuaranteed, MultiSpan, StashKey, Style,
|
||||
ErrorGuaranteed, MultiSpan, StashKey, StringPart,
|
||||
};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def::{DefKind, Namespace, Res};
|
||||
@ -2059,11 +2059,11 @@ fn report_similar_impl_candidates(
|
||||
ct_op: |ct| ct.normalize(self.tcx, ty::ParamEnv::empty()),
|
||||
});
|
||||
err.highlighted_help(vec![
|
||||
(format!("the trait `{}` ", cand.print_trait_sugared()), Style::NoStyle),
|
||||
("is".to_string(), Style::Highlight),
|
||||
(" implemented for `".to_string(), Style::NoStyle),
|
||||
(cand.self_ty().to_string(), Style::Highlight),
|
||||
("`".to_string(), Style::NoStyle),
|
||||
StringPart::normal(format!("the trait `{}` ", cand.print_trait_sugared())),
|
||||
StringPart::highlighted("is"),
|
||||
StringPart::normal(" implemented for `"),
|
||||
StringPart::highlighted(cand.self_ty().to_string()),
|
||||
StringPart::normal("`"),
|
||||
]);
|
||||
|
||||
if let [TypeError::Sorts(exp_found)] = &terrs[..] {
|
||||
@ -2095,12 +2095,12 @@ fn report_similar_impl_candidates(
|
||||
_ => (" implemented for `", ""),
|
||||
};
|
||||
err.highlighted_help(vec![
|
||||
(format!("the trait `{}` ", cand.print_trait_sugared()), Style::NoStyle),
|
||||
("is".to_string(), Style::Highlight),
|
||||
(desc.to_string(), Style::NoStyle),
|
||||
(cand.self_ty().to_string(), Style::Highlight),
|
||||
("`".to_string(), Style::NoStyle),
|
||||
(mention_castable.to_string(), Style::NoStyle),
|
||||
StringPart::normal(format!("the trait `{}` ", cand.print_trait_sugared())),
|
||||
StringPart::highlighted("is"),
|
||||
StringPart::normal(desc),
|
||||
StringPart::highlighted(cand.self_ty().to_string()),
|
||||
StringPart::normal("`"),
|
||||
StringPart::normal(mention_castable),
|
||||
]);
|
||||
return true;
|
||||
}
|
||||
|
@ -19,6 +19,6 @@
|
||||
extern crate rustc_session;
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(compiletest_example, code = 0123)]
|
||||
#[diag(compiletest_example, code = E0123)]
|
||||
//~^ ERROR diagnostic slug and crate name do not match
|
||||
struct Hello {}
|
||||
|
@ -1,7 +1,7 @@
|
||||
error: diagnostic slug and crate name do not match
|
||||
--> $DIR/enforce_slug_naming.rs:22:8
|
||||
|
|
||||
LL | #[diag(compiletest_example, code = 0123)]
|
||||
LL | #[diag(compiletest_example, code = E0123)]
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: slug is `compiletest_example` but the crate name is `rustc_dummy`
|
||||
|
Loading…
Reference in New Issue
Block a user