diff options
| author | Matthew Kelly <matthew.kelly2@gmail.com> | 2022-09-26 19:59:52 -0400 |
|---|---|---|
| committer | Matthew Kelly <matthew.kelly2@gmail.com> | 2022-09-26 19:59:52 -0400 |
| commit | 24aab524cbafec7ff8c7cd54ba4f6fb18216c623 (patch) | |
| tree | b0fd92c686ed3fe2b3a5a010c0dc32a6a54d3ea1 /compiler/rustc_errors/src | |
| parent | eda2a401457ba645a32bdc5b9e7e90214e3e4e24 (diff) | |
| parent | 8b705839cd656d202e920efa8769cbe43a5ee269 (diff) | |
| download | rust-24aab524cbafec7ff8c7cd54ba4f6fb18216c623.tar.gz rust-24aab524cbafec7ff8c7cd54ba4f6fb18216c623.zip | |
Merge remote-tracking branch 'origin/master' into mpk/add-long-error-message-for-E0311
Diffstat (limited to 'compiler/rustc_errors/src')
| -rw-r--r-- | compiler/rustc_errors/src/diagnostic.rs | 31 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/diagnostic_builder.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/emitter.rs | 30 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/lib.rs | 112 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/translation.rs | 2 |
5 files changed, 128 insertions, 60 deletions
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index f75e2596f36..1c440a0a07e 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -10,9 +10,11 @@ use rustc_lint_defs::{Applicability, LintExpectationId}; use rustc_span::edition::LATEST_STABLE_EDITION; use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol}; use rustc_span::{edition::Edition, Span, DUMMY_SP}; +use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple}; use std::borrow::Cow; use std::fmt; use std::hash::{Hash, Hasher}; +use std::num::ParseIntError; use std::path::{Path, PathBuf}; /// Error type for `Diagnostic`'s `suggestions` field, indicating that @@ -33,7 +35,7 @@ pub enum DiagnosticArgValue<'source> { Number(usize), } -/// Converts a value of a type into a `DiagnosticArg` (typically a field of a `SessionDiagnostic` +/// Converts a value of a type into a `DiagnosticArg` (typically a field of an `IntoDiagnostic` /// struct). Implemented as a custom trait rather than `From` so that it is implemented on the type /// being converted rather than on `DiagnosticArgValue`, which enables types from other `rustc_*` /// crates to implement this. @@ -90,6 +92,10 @@ into_diagnostic_arg_using_display!( Edition, Ident, MacroRulesNormalizedIdent, + ParseIntError, + StackProtector, + &TargetTriple, + SplitDebuginfo ); impl IntoDiagnosticArg for bool { @@ -144,6 +150,12 @@ impl IntoDiagnosticArg for usize { } } +impl IntoDiagnosticArg for PanicStrategy { + fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> { + DiagnosticArgValue::Str(Cow::Owned(self.desc().to_string())) + } +} + impl<'source> Into<FluentValue<'source>> for DiagnosticArgValue<'source> { fn into(self) -> FluentValue<'source> { match self { @@ -164,9 +176,10 @@ impl IntoDiagnosticArg for hir::ConstContext { } /// Trait implemented by error types. This should not be implemented manually. Instead, use -/// `#[derive(SessionSubdiagnostic)]` -- see [rustc_macros::SessionSubdiagnostic]. -#[rustc_diagnostic_item = "AddSubdiagnostic"] -pub trait AddSubdiagnostic { +/// `#[derive(Subdiagnostic)]` -- see [rustc_macros::Subdiagnostic]. +#[cfg_attr(bootstrap, rustc_diagnostic_item = "AddSubdiagnostic")] +#[cfg_attr(not(bootstrap), rustc_diagnostic_item = "AddToDiagnostic")] +pub trait AddToDiagnostic { /// Add a subdiagnostic to an existing diagnostic. fn add_to_diagnostic(self, diag: &mut Diagnostic); } @@ -878,9 +891,9 @@ impl Diagnostic { self } - /// Add a subdiagnostic from a type that implements `SessionSubdiagnostic` - see - /// [rustc_macros::SessionSubdiagnostic]. - pub fn subdiagnostic(&mut self, subdiagnostic: impl AddSubdiagnostic) -> &mut Self { + /// Add a subdiagnostic from a type that implements `Subdiagnostic` - see + /// [rustc_macros::Subdiagnostic]. + pub fn subdiagnostic(&mut self, subdiagnostic: impl AddToDiagnostic) -> &mut Self { subdiagnostic.add_to_diagnostic(self); self } @@ -974,12 +987,12 @@ impl Diagnostic { fn sub_with_highlights<M: Into<SubdiagnosticMessage>>( &mut self, level: Level, - mut message: Vec<(M, Style)>, + message: Vec<(M, Style)>, span: MultiSpan, render_span: Option<MultiSpan>, ) { let message = message - .drain(..) + .into_iter() .map(|m| (self.subdiagnostic_message_to_diagnostic_message(m.0), m.1)) .collect(); let sub = SubDiagnostic { level, message, span, render_span }; diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 61d767a1cc6..b4ba65ca96d 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -12,7 +12,16 @@ use std::fmt::{self, Debug}; use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; use std::thread::panicking; -use tracing::debug; + +/// Trait implemented by error types. This should not be implemented manually. Instead, use +/// `#[derive(Diagnostic)]` -- see [rustc_macros::Diagnostic]. +#[cfg_attr(bootstrap, rustc_diagnostic_item = "SessionDiagnostic")] +#[cfg_attr(not(bootstrap), rustc_diagnostic_item = "IntoDiagnostic")] +pub trait IntoDiagnostic<'a, T: EmissionGuarantee = ErrorGuaranteed> { + /// Write out as a diagnostic out of `Handler`. + #[must_use] + fn into_diagnostic(self, handler: &'a Handler) -> DiagnosticBuilder<'a, T>; +} /// Used for emitting structured error messages and other diagnostic information. /// @@ -571,7 +580,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> { forward!(pub fn subdiagnostic( &mut self, - subdiagnostic: impl crate::AddSubdiagnostic + subdiagnostic: impl crate::AddToDiagnostic ) -> &mut Self); } diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 6c1bfcb9919..66fbb8f1213 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -22,7 +22,7 @@ use crate::{ use rustc_lint_defs::pluralize; -use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::fx::{FxHashMap, FxIndexMap}; use rustc_data_structures::sync::Lrc; use rustc_error_messages::FluentArgs; use rustc_span::hygiene::{ExpnKind, MacroKind}; @@ -34,7 +34,6 @@ use std::iter; use std::path::Path; use termcolor::{Ansi, BufferWriter, ColorChoice, ColorSpec, StandardStream}; use termcolor::{Buffer, Color, WriteColor}; -use tracing::*; /// Default column width, used in tests and when terminal dimensions cannot be determined. const DEFAULT_COLUMN_WIDTH: usize = 140; @@ -1488,7 +1487,7 @@ impl EmitterWriter { ); // Contains the vertical lines' positions for active multiline annotations - let mut multilines = FxHashMap::default(); + let mut multilines = FxIndexMap::default(); // Get the left-side margin to remove it let mut whitespace_margin = usize::MAX; @@ -1705,7 +1704,7 @@ impl EmitterWriter { { notice_capitalization |= only_capitalization; - let has_deletion = parts.iter().any(|p| p.is_deletion()); + let has_deletion = parts.iter().any(|p| p.is_deletion(sm)); let is_multiline = complete.lines().count() > 1; if let Some(span) = span.primary_span() { @@ -1881,16 +1880,23 @@ impl EmitterWriter { let span_start_pos = sm.lookup_char_pos(part.span.lo()).col_display; let span_end_pos = sm.lookup_char_pos(part.span.hi()).col_display; + // If this addition is _only_ whitespace, then don't trim it, + // or else we're just not rendering anything. + let is_whitespace_addition = part.snippet.trim().is_empty(); + // Do not underline the leading... - let start = part.snippet.len().saturating_sub(part.snippet.trim_start().len()); + let start = if is_whitespace_addition { + 0 + } else { + part.snippet.len().saturating_sub(part.snippet.trim_start().len()) + }; // ...or trailing spaces. Account for substitutions containing unicode // characters. - let sub_len: usize = part - .snippet - .trim() - .chars() - .map(|ch| unicode_width::UnicodeWidthChar::width(ch).unwrap_or(1)) - .sum(); + let sub_len: usize = + if is_whitespace_addition { &part.snippet } else { part.snippet.trim() } + .chars() + .map(|ch| unicode_width::UnicodeWidthChar::width(ch).unwrap_or(1)) + .sum(); let offset: isize = offsets .iter() @@ -2131,7 +2137,7 @@ impl EmitterWriter { } } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] enum DisplaySuggestion { Underline, Diff, diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 68abdd0bad1..4d262ae0f5e 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -7,12 +7,10 @@ #![feature(if_let_guard)] #![feature(adt_const_params)] #![feature(let_chains)] -#![feature(let_else)] #![feature(never_type)] #![feature(result_option_inspect)] #![feature(rustc_attrs)] #![allow(incomplete_features)] -#![allow(rustc::potential_query_instability)] #[macro_use] extern crate rustc_macros; @@ -27,7 +25,7 @@ use Level::*; use emitter::{is_case_difference, Emitter, EmitterWriter}; use registry::Registry; -use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap}; +use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::stable_hasher::StableHasher; use rustc_data_structures::sync::{self, Lock, Lrc}; use rustc_data_structures::AtomicRef; @@ -61,6 +59,7 @@ mod snippet; mod styled_buffer; pub mod translation; +pub use diagnostic_builder::IntoDiagnostic; pub use snippet::Style; pub type PResult<'a, T> = Result<T, DiagnosticBuilder<'a, ErrorGuaranteed>>; @@ -70,7 +69,7 @@ pub type PResult<'a, T> = Result<T, DiagnosticBuilder<'a, ErrorGuaranteed>>; #[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"))] -rustc_data_structures::static_assert_size!(PResult<'_, bool>, 24); +rustc_data_structures::static_assert_size!(PResult<'_, bool>, 16); #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Encodable, Decodable)] pub enum SuggestionStyle { @@ -151,21 +150,20 @@ pub struct SubstitutionHighlight { impl SubstitutionPart { pub fn is_addition(&self, sm: &SourceMap) -> bool { - !self.snippet.is_empty() - && sm - .span_to_snippet(self.span) - .map_or(self.span.is_empty(), |snippet| snippet.trim().is_empty()) + !self.snippet.is_empty() && !self.replaces_meaningful_content(sm) } - pub fn is_deletion(&self) -> bool { - self.snippet.trim().is_empty() + pub fn is_deletion(&self, sm: &SourceMap) -> bool { + self.snippet.trim().is_empty() && self.replaces_meaningful_content(sm) } pub fn is_replacement(&self, sm: &SourceMap) -> bool { - !self.snippet.is_empty() - && sm - .span_to_snippet(self.span) - .map_or(!self.span.is_empty(), |snippet| !snippet.trim().is_empty()) + !self.snippet.is_empty() && self.replaces_meaningful_content(sm) + } + + fn replaces_meaningful_content(&self, sm: &SourceMap) -> bool { + sm.span_to_snippet(self.span) + .map_or(!self.span.is_empty(), |snippet| !snippet.trim().is_empty()) } } @@ -372,7 +370,7 @@ impl fmt::Display for ExplicitBug { impl error::Error for ExplicitBug {} pub use diagnostic::{ - AddSubdiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgFromDisplay, + AddToDiagnostic, DecorateLint, Diagnostic, DiagnosticArg, DiagnosticArgFromDisplay, DiagnosticArgValue, DiagnosticId, DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic, }; pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee, LintDiagnosticBuilder}; @@ -413,7 +411,7 @@ struct HandlerInner { taught_diagnostics: FxHashSet<DiagnosticId>, /// Used to suggest rustc --explain <error code> - emitted_diagnostic_codes: FxHashSet<DiagnosticId>, + emitted_diagnostic_codes: FxIndexSet<DiagnosticId>, /// This set contains a hash of every diagnostic that has been emitted by /// this handler. These hashes is used to avoid emitting the same error @@ -438,11 +436,11 @@ struct HandlerInner { /// have been converted. check_unstable_expect_diagnostics: bool, - /// Expected [`Diagnostic`]s store a [`LintExpectationId`] as part of + /// Expected [`Diagnostic`][diagnostic::Diagnostic]s store a [`LintExpectationId`] as part of /// the lint level. [`LintExpectationId`]s created early during the compilation /// (before `HirId`s have been defined) are not stable and can therefore not be /// stored on disk. This buffer stores these diagnostics until the ID has been - /// replaced by a stable [`LintExpectationId`]. The [`Diagnostic`]s are the + /// replaced by a stable [`LintExpectationId`]. The [`Diagnostic`][diagnostic::Diagnostic]s are the /// submitted for storage and added to the list of fulfilled expectations. unstable_expect_diagnostics: Vec<Diagnostic>, @@ -456,7 +454,7 @@ struct HandlerInner { } /// A key denoting where from a diagnostic was stashed. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[derive(Copy, Clone, PartialEq, Eq, Hash)] pub enum StashKey { ItemNoType, UnderscoreForArrayLengths, @@ -637,6 +635,10 @@ impl Handler { inner.steal((span, key)).map(|diag| DiagnosticBuilder::new_diagnostic(self, diag)) } + pub fn has_stashed_diagnostic(&self, span: Span, key: StashKey) -> bool { + self.inner.borrow().stashed_diagnostics.get(&(span, key)).is_some() + } + /// Emit all stashed diagnostics. pub fn emit_stashed_diagnostics(&self) -> Option<ErrorGuaranteed> { self.inner.borrow_mut().emit_stashed_diagnostics() @@ -1026,6 +1028,39 @@ impl Handler { self.inner.borrow_mut().emit_diagnostic(diagnostic) } + pub fn emit_err<'a>(&'a self, err: impl IntoDiagnostic<'a>) -> ErrorGuaranteed { + self.create_err(err).emit() + } + + pub fn create_err<'a>( + &'a self, + err: impl IntoDiagnostic<'a>, + ) -> DiagnosticBuilder<'a, ErrorGuaranteed> { + err.into_diagnostic(self) + } + + pub fn create_warning<'a>( + &'a self, + warning: impl IntoDiagnostic<'a, ()>, + ) -> DiagnosticBuilder<'a, ()> { + warning.into_diagnostic(self) + } + + pub fn emit_warning<'a>(&'a self, warning: impl IntoDiagnostic<'a, ()>) { + self.create_warning(warning).emit() + } + + pub fn create_fatal<'a>( + &'a self, + fatal: impl IntoDiagnostic<'a, !>, + ) -> DiagnosticBuilder<'a, !> { + fatal.into_diagnostic(self) + } + + pub fn emit_fatal<'a>(&'a self, fatal: impl IntoDiagnostic<'a, !>) -> ! { + self.create_fatal(fatal).emit() + } + fn emit_diag_at_span( &self, mut diag: Diagnostic, @@ -1250,14 +1285,14 @@ impl HandlerInner { fn treat_err_as_bug(&self) -> bool { self.flags.treat_err_as_bug.map_or(false, |c| { - self.err_count() - + self.lint_err_count - + self.delayed_span_bugs.len() - + self.delayed_good_path_bugs.len() - >= c.get() + self.err_count() + self.lint_err_count + self.delayed_bug_count() >= c.get() }) } + fn delayed_bug_count(&self) -> usize { + self.delayed_span_bugs.len() + self.delayed_good_path_bugs.len() + } + fn print_error_count(&mut self, registry: &Registry) { self.emit_stashed_diagnostics(); @@ -1412,12 +1447,7 @@ impl HandlerInner { // incrementing `err_count` by one, so we need to +1 the comparing. // FIXME: Would be nice to increment err_count in a more coherent way. if self.flags.treat_err_as_bug.map_or(false, |c| { - self.err_count() - + self.lint_err_count - + self.delayed_span_bugs.len() - + self.delayed_good_path_bugs.len() - + 1 - >= c.get() + self.err_count() + self.lint_err_count + self.delayed_bug_count() + 1 >= c.get() }) { // FIXME: don't abort here if report_delayed_bugs is off self.span_bug(sp, msg); @@ -1518,14 +1548,24 @@ impl HandlerInner { if self.treat_err_as_bug() { match ( self.err_count() + self.lint_err_count, + self.delayed_bug_count(), self.flags.treat_err_as_bug.map(|c| c.get()).unwrap_or(0), ) { - (1, 1) => panic!("aborting due to `-Z treat-err-as-bug=1`"), - (0 | 1, _) => {} - (count, as_bug) => panic!( - "aborting after {} errors due to `-Z treat-err-as-bug={}`", - count, as_bug, - ), + (1, 0, 1) => panic!("aborting due to `-Z treat-err-as-bug=1`"), + (0, 1, 1) => panic!("aborting due delayed bug with `-Z treat-err-as-bug=1`"), + (count, delayed_count, as_bug) => { + if delayed_count > 0 { + panic!( + "aborting after {} errors and {} delayed bugs due to `-Z treat-err-as-bug={}`", + count, delayed_count, as_bug, + ) + } else { + panic!( + "aborting after {} errors due to `-Z treat-err-as-bug={}`", + count, as_bug, + ) + } + } } } } diff --git a/compiler/rustc_errors/src/translation.rs b/compiler/rustc_errors/src/translation.rs index 65338f56d9c..4f407badb3f 100644 --- a/compiler/rustc_errors/src/translation.rs +++ b/compiler/rustc_errors/src/translation.rs @@ -21,7 +21,7 @@ pub trait Translate { /// Typically performed once for each diagnostic at the start of `emit_diagnostic` and then /// passed around as a reference thereafter. fn to_fluent_args<'arg>(&self, args: &[DiagnosticArg<'arg>]) -> FluentArgs<'arg> { - FromIterator::from_iter(args.to_vec().drain(..)) + FromIterator::from_iter(args.iter().cloned()) } /// Convert `DiagnosticMessage`s to a string, performing translation if necessary. |
