Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Miscellaneous diagnostics cleanups #120571

Merged
merged 14 commits into from
Feb 4, 2024
Merged
4 changes: 2 additions & 2 deletions compiler/rustc_borrowck/src/diagnostics/mutability_errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,12 +198,12 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
{
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);
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ pub(crate) struct ParseTargetMachineConfig<'a>(pub LlvmError<'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)
Expand Down
5 changes: 2 additions & 3 deletions compiler/rustc_codegen_ssa/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ use rustc_target::spec::{MergeFunctions, SanitizerSet};

use crate::errors::ErrorCreatingRemarkDir;
use std::any::Any;
use std::borrow::Cow;
use std::fs;
use std::io;
use std::marker::PhantomData;
Expand Down Expand Up @@ -1812,12 +1811,12 @@ impl Translate for SharedEmitter {

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 {
Expand Down
9 changes: 4 additions & 5 deletions compiler/rustc_const_eval/src/const_eval/error.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -32,10 +34,7 @@ impl MachineStopType for ConstEvalErrKind {
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 => {}
Expand Down
96 changes: 37 additions & 59 deletions compiler/rustc_errors/src/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@ pub type DiagnosticArgName = Cow<'static, str>;
#[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>>),
}

Expand Down Expand Up @@ -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)]
Expand Down Expand Up @@ -162,10 +165,10 @@ impl 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 {
Expand All @@ -175,35 +178,34 @@ impl DiagnosticStyledString {
}
}
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 {
Expand Down Expand Up @@ -389,19 +391,16 @@ impl Diagnostic {
} 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);
Expand All @@ -410,9 +409,9 @@ impl Diagnostic {

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
}
Expand All @@ -424,10 +423,7 @@ impl Diagnostic {
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
}
Expand Down Expand Up @@ -496,7 +492,7 @@ impl Diagnostic {
}

/// 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
}
Expand Down Expand Up @@ -890,15 +886,6 @@ impl Diagnostic {
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
Expand All @@ -913,7 +900,7 @@ impl Diagnostic {

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());
Expand All @@ -924,10 +911,6 @@ impl Diagnostic {
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).
Expand Down Expand Up @@ -958,15 +941,10 @@ impl Diagnostic {

/// 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);
Expand Down
8 changes: 2 additions & 6 deletions compiler/rustc_errors/src/diagnostic_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
14 changes: 6 additions & 8 deletions compiler/rustc_errors/src/emitter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ impl Emitter for HumanEmitter {
/// 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 {
Expand All @@ -576,13 +576,11 @@ impl Emitter for SilentEmitter {
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);
}
}
}
Expand Down
Loading
Loading