diff options
| author | bors <bors@rust-lang.org> | 2024-09-25 06:41:56 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-09-25 06:41:56 +0000 |
| commit | 34aff74fb06e78fb9cd1a66acafb6d150638de35 (patch) | |
| tree | 14533de260c2f1834994e58af1d210a6884625a9 /compiler/rustc_errors/src | |
| parent | 938c7b1162a38dca257c7004ef7ecf86397a8634 (diff) | |
| parent | 8be19465ec14880160d294f2909202451a547740 (diff) | |
| download | rust-34aff74fb06e78fb9cd1a66acafb6d150638de35.tar.gz rust-34aff74fb06e78fb9cd1a66acafb6d150638de35.zip | |
Auto merge of #18183 - lnicola:sync-from-rust, r=lnicola
internal: Sync from downstream
Diffstat (limited to 'compiler/rustc_errors/src')
| -rw-r--r-- | compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/diagnostic.rs | 73 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/diagnostic_impls.rs | 6 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/emitter.rs | 10 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/json.rs | 20 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/json/tests.rs | 162 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/lib.rs | 149 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/lock.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/markdown/parse.rs | 2 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/tests.rs | 4 |
10 files changed, 178 insertions, 258 deletions
diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs index d71ae9d210d..f468fbf4497 100644 --- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs +++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs @@ -8,12 +8,12 @@ use annotate_snippets::{Renderer, Snippet}; use rustc_data_structures::sync::Lrc; use rustc_error_messages::FluentArgs; -use rustc_span::source_map::SourceMap; use rustc_span::SourceFile; +use rustc_span::source_map::SourceMap; use crate::emitter::FileWithAnnotatedLines; use crate::snippet::Line; -use crate::translation::{to_fluent_args, Translate}; +use crate::translation::{Translate, to_fluent_args}; use crate::{ CodeSuggestion, DiagInner, DiagMessage, Emitter, ErrCode, FluentBundle, LazyFallbackBundle, Level, MultiSpan, Style, Subdiag, @@ -48,7 +48,7 @@ impl Emitter for AnnotateSnippetEmitter { fn emit_diagnostic(&mut self, mut diag: DiagInner) { let fluent_args = to_fluent_args(diag.args.iter()); - let mut suggestions = diag.suggestions.unwrap_or(vec![]); + let mut suggestions = diag.suggestions.unwrap_tag(); self.primary_span_formatted(&mut diag.span, &mut suggestions, &fluent_args); self.fix_multispans_in_extern_macros_and_render_macro_backtrace( diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs index 3303e4ee752..4352de3ad25 100644 --- a/compiler/rustc_errors/src/diagnostic.rs +++ b/compiler/rustc_errors/src/diagnostic.rs @@ -7,25 +7,21 @@ use std::panic; use std::thread::panicking; use rustc_data_structures::fx::FxIndexMap; -use rustc_error_messages::{fluent_value_from_str_list_sep_by_and, FluentValue}; -use rustc_lint_defs::{Applicability, LintExpectationId}; +use rustc_error_messages::{FluentValue, fluent_value_from_str_list_sep_by_and}; +use rustc_lint_defs::Applicability; use rustc_macros::{Decodable, Encodable}; use rustc_span::source_map::Spanned; use rustc_span::symbol::Symbol; -use rustc_span::{Span, DUMMY_SP}; +use rustc_span::{DUMMY_SP, Span}; use tracing::debug; use crate::snippet::Style; use crate::{ CodeSuggestion, DiagCtxtHandle, DiagMessage, ErrCode, ErrorGuaranteed, ExplicitBug, Level, MultiSpan, StashKey, SubdiagMessage, Substitution, SubstitutionPart, SuggestionStyle, + Suggestions, }; -/// Error type for `DiagInner`'s `suggestions` field, indicating that -/// `.disable_suggestions()` was called on the `DiagInner`. -#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)] -pub struct SuggestionsDisabled; - /// Simplified version of `FluentArg` that can implement `Encodable` and `Decodable`. Collection of /// `DiagArg` are converted to `FluentArgs` (consuming the collection) at the start of diagnostic /// emission. @@ -296,7 +292,7 @@ pub struct DiagInner { pub code: Option<ErrCode>, pub span: MultiSpan, pub children: Vec<Subdiag>, - pub suggestions: Result<Vec<CodeSuggestion>, SuggestionsDisabled>, + pub suggestions: Suggestions, pub args: DiagArgMap, /// This is not used for highlighting or rendering any error message. Rather, it can be used @@ -325,7 +321,7 @@ impl DiagInner { code: None, span: MultiSpan::new(), children: vec![], - suggestions: Ok(vec![]), + suggestions: Suggestions::Enabled(vec![]), args: Default::default(), sort_span: DUMMY_SP, is_lint: None, @@ -354,31 +350,6 @@ impl DiagInner { } } - pub(crate) fn update_unstable_expectation_id( - &mut self, - unstable_to_stable: &FxIndexMap<LintExpectationId, LintExpectationId>, - ) { - if let Level::Expect(expectation_id) | Level::ForceWarning(Some(expectation_id)) = - &mut self.level - { - if expectation_id.is_stable() { - return; - } - - // The unstable to stable map only maps the unstable `AttrId` to a stable `HirId` with an attribute index. - // The lint index inside the attribute is manually transferred here. - let lint_index = expectation_id.get_lint_index(); - expectation_id.set_lint_index(None); - let mut stable_id = unstable_to_stable - .get(expectation_id) - .expect("each unstable `LintExpectationId` must have a matching stable id") - .normalize(); - - stable_id.set_lint_index(lint_index); - *expectation_id = stable_id; - } - } - /// Indicates whether this diagnostic should show up in cargo's future breakage report. pub(crate) fn has_future_breakage(&self) -> bool { matches!(self.is_lint, Some(IsLint { has_future_breakage: true, .. })) @@ -434,7 +405,7 @@ impl DiagInner { &Option<ErrCode>, &MultiSpan, &[Subdiag], - &Result<Vec<CodeSuggestion>, SuggestionsDisabled>, + &Suggestions, Vec<(&DiagArgName, &DiagArgValue)>, &Option<IsLint>, ) { @@ -484,7 +455,7 @@ pub struct Subdiag { /// - The `EmissionGuarantee`, which determines the type returned from `emit`. /// /// Each constructed `Diag` must be consumed by a function such as `emit`, -/// `cancel`, `delay_as_bug`, or `into_diag`. A panic occurrs if a `Diag` +/// `cancel`, `delay_as_bug`, or `into_diag`. A panic occurs if a `Diag` /// is dropped without being consumed by one of these functions. /// /// If there is some state in a downstream crate you would like to access in @@ -706,10 +677,10 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { " ".repeat(expected_padding), expected_label ))]; - msg.extend(expected.0.into_iter()); + msg.extend(expected.0); 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.extend(found.0); msg.push(StringPart::normal(format!("`{found_extra}"))); // For now, just attach these as notes. @@ -848,16 +819,32 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { self } - /// Disallow attaching suggestions this diagnostic. + /// Disallow attaching suggestions to this diagnostic. /// Any suggestions attached e.g. with the `span_suggestion_*` methods /// (before and after the call to `disable_suggestions`) will be ignored. #[rustc_lint_diagnostics] pub fn disable_suggestions(&mut self) -> &mut Self { - self.suggestions = Err(SuggestionsDisabled); + self.suggestions = Suggestions::Disabled; + self + } + + /// Prevent new suggestions from being added to this diagnostic. + /// + /// Suggestions added before the call to `.seal_suggestions()` will be preserved + /// and new suggestions will be ignored. + #[rustc_lint_diagnostics] + pub fn seal_suggestions(&mut self) -> &mut Self { + if let Suggestions::Enabled(suggestions) = &mut self.suggestions { + let suggestions_slice = std::mem::take(suggestions).into_boxed_slice(); + self.suggestions = Suggestions::Sealed(suggestions_slice); + } self } - /// Helper for pushing to `self.suggestions`, if available (not disable). + /// Helper for pushing to `self.suggestions`. + /// + /// A new suggestion is added if suggestions are enabled for this diagnostic. + /// Otherwise, they are ignored. #[rustc_lint_diagnostics] fn push_suggestion(&mut self, suggestion: CodeSuggestion) { for subst in &suggestion.substitutions { @@ -871,7 +858,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> { } } - if let Ok(suggestions) = &mut self.suggestions { + if let Suggestions::Enabled(suggestions) = &mut self.suggestions { suggestions.push(suggestion); } } diff --git a/compiler/rustc_errors/src/diagnostic_impls.rs b/compiler/rustc_errors/src/diagnostic_impls.rs index 9e3bc3e60b1..19529f06ef1 100644 --- a/compiler/rustc_errors/src/diagnostic_impls.rs +++ b/compiler/rustc_errors/src/diagnostic_impls.rs @@ -7,9 +7,9 @@ use std::process::ExitStatus; use rustc_ast_pretty::pprust; use rustc_macros::Subdiagnostic; +use rustc_span::Span; use rustc_span::edition::Edition; use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol}; -use rustc_span::Span; use rustc_target::abi::TargetDataLayoutErrors; use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple}; use rustc_type_ir::{ClosureKind, FloatTy}; @@ -17,8 +17,8 @@ use {rustc_ast as ast, rustc_hir as hir}; use crate::diagnostic::DiagLocation; use crate::{ - fluent_generated as fluent, Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, - ErrCode, IntoDiagArg, Level, SubdiagMessageOp, Subdiagnostic, + Diag, DiagArgValue, DiagCtxtHandle, Diagnostic, EmissionGuarantee, ErrCode, IntoDiagArg, Level, + SubdiagMessageOp, Subdiagnostic, fluent_generated as fluent, }; pub struct DiagArgFromDisplay<'a>(pub &'a dyn fmt::Display); diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs index 2bc29dabd18..1dc52c4d0a4 100644 --- a/compiler/rustc_errors/src/emitter.rs +++ b/compiler/rustc_errors/src/emitter.rs @@ -8,7 +8,7 @@ //! The output types are defined in `rustc_session::config::ErrorOutputType`. use std::borrow::Cow; -use std::cmp::{max, min, Reverse}; +use std::cmp::{Reverse, max, min}; use std::error::Report; use std::io::prelude::*; use std::io::{self, IsTerminal}; @@ -22,7 +22,7 @@ use rustc_error_messages::{FluentArgs, SpanLabel}; use rustc_lint_defs::pluralize; use rustc_span::hygiene::{ExpnKind, MacroKind}; use rustc_span::source_map::SourceMap; -use rustc_span::{char_width, FileLines, FileName, SourceFile, Span}; +use rustc_span::{FileLines, FileName, SourceFile, Span, char_width}; use termcolor::{Buffer, BufferWriter, Color, ColorChoice, ColorSpec, StandardStream, WriteColor}; use tracing::{debug, instrument, trace, warn}; @@ -31,7 +31,7 @@ use crate::snippet::{ Annotation, AnnotationColumn, AnnotationType, Line, MultilineAnnotation, Style, StyledString, }; use crate::styled_buffer::StyledBuffer; -use crate::translation::{to_fluent_args, Translate}; +use crate::translation::{Translate, to_fluent_args}; use crate::{ CodeSuggestion, DiagCtxt, DiagInner, DiagMessage, ErrCode, FluentBundle, LazyFallbackBundle, Level, MultiSpan, Subdiag, SubstitutionHighlight, SuggestionStyle, TerminalUrl, @@ -498,7 +498,7 @@ impl Emitter for HumanEmitter { fn emit_diagnostic(&mut self, mut diag: DiagInner) { let fluent_args = to_fluent_args(diag.args.iter()); - let mut suggestions = diag.suggestions.unwrap_or(vec![]); + let mut suggestions = diag.suggestions.unwrap_tag(); self.primary_span_formatted(&mut diag.span, &mut suggestions, &fluent_args); self.fix_multispans_in_extern_macros_and_render_macro_backtrace( @@ -2300,7 +2300,7 @@ impl HumanEmitter { // For example, for the following: // | // 2 - .await - // 2 + (note the left over whitepsace) + // 2 + (note the left over whitespace) // | // We really want // | diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs index 32e59f9ab03..1972a522e39 100644 --- a/compiler/rustc_errors/src/json.rs +++ b/compiler/rustc_errors/src/json.rs @@ -19,21 +19,22 @@ use derive_setters::Setters; use rustc_data_structures::sync::{IntoDynSyncSend, Lrc}; use rustc_error_messages::FluentArgs; use rustc_lint_defs::Applicability; +use rustc_span::Span; use rustc_span::hygiene::ExpnData; use rustc_span::source_map::SourceMap; -use rustc_span::Span; use serde::Serialize; use termcolor::{ColorSpec, WriteColor}; use crate::diagnostic::IsLint; use crate::emitter::{ - should_show_source_code, ColorConfig, Destination, Emitter, HumanEmitter, - HumanReadableErrorType, + ColorConfig, Destination, Emitter, HumanEmitter, HumanReadableErrorType, + should_show_source_code, }; use crate::registry::Registry; -use crate::translation::{to_fluent_args, Translate}; +use crate::translation::{Translate, to_fluent_args}; use crate::{ - CodeSuggestion, FluentBundle, LazyFallbackBundle, MultiSpan, SpanLabel, Subdiag, TerminalUrl, + CodeSuggestion, FluentBundle, LazyFallbackBundle, MultiSpan, SpanLabel, Subdiag, Suggestions, + TerminalUrl, }; #[cfg(test)] @@ -292,7 +293,7 @@ impl Diagnostic { /// Converts from `rustc_errors::DiagInner` to `Diagnostic`. fn from_errors_diagnostic(diag: crate::DiagInner, je: &JsonEmitter) -> Diagnostic { let args = to_fluent_args(diag.args.iter()); - let sugg = diag.suggestions.iter().flatten().map(|sugg| { + let sugg_to_diag = |sugg: &CodeSuggestion| { let translated_message = je.translate_message(&sugg.msg, &args).map_err(Report::new).unwrap(); Diagnostic { @@ -303,7 +304,12 @@ impl Diagnostic { children: vec![], rendered: None, } - }); + }; + let sugg = match &diag.suggestions { + Suggestions::Enabled(suggestions) => suggestions.iter().map(sugg_to_diag), + Suggestions::Sealed(suggestions) => suggestions.iter().map(sugg_to_diag), + Suggestions::Disabled => [].iter().map(sugg_to_diag), + }; // generate regular command line output and store it in the json diff --git a/compiler/rustc_errors/src/json/tests.rs b/compiler/rustc_errors/src/json/tests.rs index 6af376d7afd..0de555b83d3 100644 --- a/compiler/rustc_errors/src/json/tests.rs +++ b/compiler/rustc_errors/src/json/tests.rs @@ -1,7 +1,7 @@ use std::str; -use rustc_span::source_map::FilePathMapping; use rustc_span::BytePos; +use rustc_span::source_map::FilePathMapping; use serde::Deserialize; use super::*; @@ -69,128 +69,96 @@ fn test_positions(code: &str, span: (u32, u32), expected_output: SpanTestData) { #[test] fn empty() { - test_positions( - " ", - (0, 1), - SpanTestData { - byte_start: 0, - byte_end: 1, - line_start: 1, - column_start: 1, - line_end: 1, - column_end: 2, - }, - ) + test_positions(" ", (0, 1), SpanTestData { + byte_start: 0, + byte_end: 1, + line_start: 1, + column_start: 1, + line_end: 1, + column_end: 2, + }) } #[test] fn bom() { - test_positions( - "\u{feff} ", - (0, 1), - SpanTestData { - byte_start: 3, - byte_end: 4, - line_start: 1, - column_start: 1, - line_end: 1, - column_end: 2, - }, - ) + test_positions("\u{feff} ", (0, 1), SpanTestData { + byte_start: 3, + byte_end: 4, + line_start: 1, + column_start: 1, + line_end: 1, + column_end: 2, + }) } #[test] fn lf_newlines() { - test_positions( - "\nmod foo;\nmod bar;\n", - (5, 12), - SpanTestData { - byte_start: 5, - byte_end: 12, - line_start: 2, - column_start: 5, - line_end: 3, - column_end: 3, - }, - ) + test_positions("\nmod foo;\nmod bar;\n", (5, 12), SpanTestData { + byte_start: 5, + byte_end: 12, + line_start: 2, + column_start: 5, + line_end: 3, + column_end: 3, + }) } #[test] fn crlf_newlines() { - test_positions( - "\r\nmod foo;\r\nmod bar;\r\n", - (5, 12), - SpanTestData { - byte_start: 6, - byte_end: 14, - line_start: 2, - column_start: 5, - line_end: 3, - column_end: 3, - }, - ) + test_positions("\r\nmod foo;\r\nmod bar;\r\n", (5, 12), SpanTestData { + byte_start: 6, + byte_end: 14, + line_start: 2, + column_start: 5, + line_end: 3, + column_end: 3, + }) } #[test] fn crlf_newlines_with_bom() { - test_positions( - "\u{feff}\r\nmod foo;\r\nmod bar;\r\n", - (5, 12), - SpanTestData { - byte_start: 9, - byte_end: 17, - line_start: 2, - column_start: 5, - line_end: 3, - column_end: 3, - }, - ) + test_positions("\u{feff}\r\nmod foo;\r\nmod bar;\r\n", (5, 12), SpanTestData { + byte_start: 9, + byte_end: 17, + line_start: 2, + column_start: 5, + line_end: 3, + column_end: 3, + }) } #[test] fn span_before_crlf() { - test_positions( - "foo\r\nbar", - (2, 3), - SpanTestData { - byte_start: 2, - byte_end: 3, - line_start: 1, - column_start: 3, - line_end: 1, - column_end: 4, - }, - ) + test_positions("foo\r\nbar", (2, 3), SpanTestData { + byte_start: 2, + byte_end: 3, + line_start: 1, + column_start: 3, + line_end: 1, + column_end: 4, + }) } #[test] fn span_on_crlf() { - test_positions( - "foo\r\nbar", - (3, 4), - SpanTestData { - byte_start: 3, - byte_end: 5, - line_start: 1, - column_start: 4, - line_end: 2, - column_end: 1, - }, - ) + test_positions("foo\r\nbar", (3, 4), SpanTestData { + byte_start: 3, + byte_end: 5, + line_start: 1, + column_start: 4, + line_end: 2, + column_end: 1, + }) } #[test] fn span_after_crlf() { - test_positions( - "foo\r\nbar", - (4, 5), - SpanTestData { - byte_start: 5, - byte_end: 6, - line_start: 2, - column_start: 1, - line_end: 2, - column_end: 2, - }, - ) + test_positions("foo\r\nbar", (4, 5), SpanTestData { + byte_start: 5, + byte_end: 6, + line_start: 2, + column_start: 1, + line_end: 2, + column_end: 2, + }) } diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 99ee8fb17d7..39acacfbe59 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -42,6 +42,7 @@ use std::ops::DerefMut; use std::path::{Path, PathBuf}; use std::{fmt, panic}; +use Level::*; pub use codes::*; pub use diagnostic::{ BugAbort, Diag, DiagArg, DiagArgMap, DiagArgName, DiagArgValue, DiagInner, DiagStyledString, @@ -53,29 +54,28 @@ pub use diagnostic_impls::{ IndicateAnonymousLifetime, SingleLabelManySpans, }; pub use emitter::ColorConfig; -use emitter::{is_case_difference, is_different, DynEmitter, Emitter}; +use emitter::{DynEmitter, Emitter, is_case_difference, is_different}; use registry::Registry; +use rustc_data_structures::AtomicRef; use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; use rustc_data_structures::stable_hasher::{Hash128, StableHasher}; use rustc_data_structures::sync::{Lock, Lrc}; -use rustc_data_structures::AtomicRef; pub use rustc_error_messages::{ - fallback_fluent_bundle, fluent_bundle, DiagMessage, FluentBundle, LanguageIdentifier, - LazyFallbackBundle, MultiSpan, SpanLabel, SubdiagMessage, + DiagMessage, FluentBundle, LanguageIdentifier, LazyFallbackBundle, MultiSpan, SpanLabel, + SubdiagMessage, fallback_fluent_bundle, fluent_bundle, }; use rustc_lint_defs::LintExpectationId; -pub use rustc_lint_defs::{pluralize, Applicability}; +pub use rustc_lint_defs::{Applicability, pluralize}; use rustc_macros::{Decodable, Encodable}; +pub use rustc_span::ErrorGuaranteed; pub use rustc_span::fatal_error::{FatalError, FatalErrorMarker}; use rustc_span::source_map::SourceMap; -pub use rustc_span::ErrorGuaranteed; -use rustc_span::{Loc, Span, DUMMY_SP}; +use rustc_span::{DUMMY_SP, Loc, Span}; pub use snippet::Style; // Used by external projects such as `rust-gpu`. // See https://github.com/rust-lang/rust/pull/115393. pub use termcolor::{Color, ColorSpec, WriteColor}; use tracing::debug; -use Level::*; pub mod annotate_snippet_emitter_writer; pub mod codes; @@ -126,6 +126,41 @@ impl SuggestionStyle { } } +/// Represents the help messages seen on a diagnostic. +#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)] +pub enum Suggestions { + /// Indicates that new suggestions can be added or removed from this diagnostic. + /// + /// `DiagInner`'s new_* methods initialize the `suggestions` field with + /// this variant. Also, this is the default variant for `Suggestions`. + Enabled(Vec<CodeSuggestion>), + /// Indicates that suggestions cannot be added or removed from this diagnostic. + /// + /// Gets toggled when `.seal_suggestions()` is called on the `DiagInner`. + Sealed(Box<[CodeSuggestion]>), + /// Indicates that no suggestion is available for this diagnostic. + /// + /// Gets toggled when `.disable_suggestions()` is called on the `DiagInner`. + Disabled, +} + +impl Suggestions { + /// Returns the underlying list of suggestions. + pub fn unwrap_tag(self) -> Vec<CodeSuggestion> { + match self { + Suggestions::Enabled(suggestions) => suggestions, + Suggestions::Sealed(suggestions) => suggestions.into_vec(), + Suggestions::Disabled => Vec::new(), + } + } +} + +impl Default for Suggestions { + fn default() -> Self { + Self::Enabled(vec![]) + } +} + #[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)] pub struct CodeSuggestion { /// Each substitute can have multiple variants due to multiple @@ -497,28 +532,18 @@ struct DiagCtxtInner { future_breakage_diagnostics: Vec<DiagInner>, - /// The [`Self::unstable_expect_diagnostics`] should be empty when this struct is - /// dropped. However, it can have values if the compilation is stopped early - /// or is only partially executed. To avoid ICEs, like in rust#94953 we only - /// check if [`Self::unstable_expect_diagnostics`] is empty, if the expectation ids - /// have been converted. - check_unstable_expect_diagnostics: bool, - - /// Expected [`DiagInner`][struct@diagnostic::DiagInner]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 [`DiagInner`][struct@diagnostic::DiagInner]s - /// are submitted for storage and added to the list of fulfilled expectations. - unstable_expect_diagnostics: Vec<DiagInner>, - /// expected diagnostic will have the level `Expect` which additionally /// carries the [`LintExpectationId`] of the expectation that can be /// marked as fulfilled. This is a collection of all [`LintExpectationId`]s /// that have been marked as fulfilled this way. /// + /// Emitting expectations after having stolen this field can happen. In particular, an + /// `#[expect(warnings)]` can easily make the `UNFULFILLED_LINT_EXPECTATIONS` lint expect + /// itself. To avoid needless complexity in this corner case, we tolerate failing to track + /// those expectations. + /// /// [RFC-2383]: https://rust-lang.github.io/rfcs/2383-lint-reasons.html - fulfilled_expectations: FxHashSet<LintExpectationId>, + fulfilled_expectations: FxIndexSet<LintExpectationId>, /// The file where the ICE information is stored. This allows delayed_span_bug backtraces to be /// stored along side the main panic backtrace. @@ -546,6 +571,8 @@ pub enum StashKey { /// Query cycle detected, stashing in favor of a better error. Cycle, UndeterminedMacroResolution, + /// Used by `Parser::maybe_recover_trailing_expr` + ExprInPat, } fn default_track_diagnostic<R>(diag: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) -> R { @@ -605,13 +632,6 @@ impl Drop for DiagCtxtInner { ); } } - - if self.check_unstable_expect_diagnostics { - assert!( - self.unstable_expect_diagnostics.is_empty(), - "all diagnostics with unstable expectations should have been converted", - ); - } } } @@ -740,8 +760,6 @@ impl DiagCtxt { emitted_diagnostics, stashed_diagnostics, future_breakage_diagnostics, - check_unstable_expect_diagnostics, - unstable_expect_diagnostics, fulfilled_expectations, ice_file: _, } = inner.deref_mut(); @@ -761,8 +779,6 @@ impl DiagCtxt { *emitted_diagnostics = Default::default(); *stashed_diagnostics = Default::default(); *future_breakage_diagnostics = Default::default(); - *check_unstable_expect_diagnostics = false; - *unstable_expect_diagnostics = Default::default(); *fulfilled_expectations = Default::default(); } @@ -817,7 +833,7 @@ impl<'a> DiagCtxtHandle<'a> { ); } // We delay a bug here so that `-Ztreat-err-as-bug -Zeagerly-emit-delayed-bugs` - // can be used to create a backtrace at the stashing site insted of whenever the + // can be used to create a backtrace at the stashing site instead of whenever the // diagnostic context is dropped and thus delayed bugs are emitted. Error => Some(self.span_delayed_bug(span, format!("stashing {key:?}"))), DelayedBug => { @@ -1094,44 +1110,10 @@ impl<'a> DiagCtxtHandle<'a> { inner.emitter.emit_unused_externs(lint_level, unused_externs) } - pub fn update_unstable_expectation_id( - &self, - unstable_to_stable: &FxIndexMap<LintExpectationId, LintExpectationId>, - ) { - let mut inner = self.inner.borrow_mut(); - let diags = std::mem::take(&mut inner.unstable_expect_diagnostics); - inner.check_unstable_expect_diagnostics = true; - - if !diags.is_empty() { - inner.suppressed_expected_diag = true; - for mut diag in diags.into_iter() { - diag.update_unstable_expectation_id(unstable_to_stable); - - // Here the diagnostic is given back to `emit_diagnostic` where it was first - // intercepted. Now it should be processed as usual, since the unstable expectation - // id is now stable. - inner.emit_diagnostic(diag, self.tainted_with_errors); - } - } - - inner - .stashed_diagnostics - .values_mut() - .for_each(|(diag, _guar)| diag.update_unstable_expectation_id(unstable_to_stable)); - inner - .future_breakage_diagnostics - .iter_mut() - .for_each(|diag| diag.update_unstable_expectation_id(unstable_to_stable)); - } - /// This methods steals all [`LintExpectationId`]s that are stored inside /// [`DiagCtxtInner`] and indicate that the linked expectation has been fulfilled. #[must_use] - pub fn steal_fulfilled_expectation_ids(&self) -> FxHashSet<LintExpectationId> { - assert!( - self.inner.borrow().unstable_expect_diagnostics.is_empty(), - "`DiagCtxtInner::unstable_expect_diagnostics` should be empty at this point", - ); + pub fn steal_fulfilled_expectation_ids(&self) -> FxIndexSet<LintExpectationId> { std::mem::take(&mut self.inner.borrow_mut().fulfilled_expectations) } @@ -1440,8 +1422,6 @@ impl DiagCtxtInner { emitted_diagnostics: Default::default(), stashed_diagnostics: Default::default(), future_breakage_diagnostics: Vec::new(), - check_unstable_expect_diagnostics: false, - unstable_expect_diagnostics: Vec::new(), fulfilled_expectations: Default::default(), ice_file: None, } @@ -1471,24 +1451,6 @@ impl DiagCtxtInner { mut diagnostic: DiagInner, taint: Option<&Cell<Option<ErrorGuaranteed>>>, ) -> Option<ErrorGuaranteed> { - match diagnostic.level { - Expect(expect_id) | ForceWarning(Some(expect_id)) => { - // The `LintExpectationId` can be stable or unstable depending on when it was - // created. Diagnostics created before the definition of `HirId`s are unstable and - // can not yet be stored. Instead, they are buffered until the `LintExpectationId` - // is replaced by a stable one by the `LintLevelsBuilder`. - if let LintExpectationId::Unstable { .. } = expect_id { - // We don't call TRACK_DIAGNOSTIC because we wait for the - // unstable ID to be updated, whereupon the diagnostic will be - // passed into this method again. - self.unstable_expect_diagnostics.push(diagnostic); - return None; - } - // Continue through to the `Expect`/`ForceWarning` case below. - } - _ => {} - } - if diagnostic.has_future_breakage() { // Future breakages aren't emitted if they're `Level::Allow` or // `Level::Expect`, but they still need to be constructed and @@ -1564,10 +1526,7 @@ impl DiagCtxtInner { return None; } Expect(expect_id) | ForceWarning(Some(expect_id)) => { - if let LintExpectationId::Unstable { .. } = expect_id { - unreachable!(); // this case was handled at the top of this function - } - self.fulfilled_expectations.insert(expect_id.normalize()); + self.fulfilled_expectations.insert(expect_id); if let Expect(_) = diagnostic.level { // Nothing emitted here for expected lints. TRACK_DIAGNOSTIC(diagnostic, &mut |_| None); diff --git a/compiler/rustc_errors/src/lock.rs b/compiler/rustc_errors/src/lock.rs index 7557969f374..85199c34a14 100644 --- a/compiler/rustc_errors/src/lock.rs +++ b/compiler/rustc_errors/src/lock.rs @@ -16,11 +16,11 @@ pub(crate) fn acquire_global_lock(name: &str) -> Box<dyn Any> { use std::ffi::CString; use std::io; - use windows::core::PCSTR; use windows::Win32::Foundation::{CloseHandle, HANDLE, WAIT_ABANDONED, WAIT_OBJECT_0}; use windows::Win32::System::Threading::{ - CreateMutexA, ReleaseMutex, WaitForSingleObject, INFINITE, + CreateMutexA, INFINITE, ReleaseMutex, WaitForSingleObject, }; + use windows::core::PCSTR; struct Handle(HANDLE); diff --git a/compiler/rustc_errors/src/markdown/parse.rs b/compiler/rustc_errors/src/markdown/parse.rs index b1db44dd215..8dd146c1c33 100644 --- a/compiler/rustc_errors/src/markdown/parse.rs +++ b/compiler/rustc_errors/src/markdown/parse.rs @@ -487,7 +487,7 @@ fn is_break_ty(val: &MdTree<'_>) -> bool { || matches!(val, MdTree::PlainText(txt) if txt.trim().is_empty()) } -/// Perform tranformations to text. This splits paragraphs, replaces patterns, +/// Perform transformations to text. This splits paragraphs, replaces patterns, /// and corrects newlines. /// /// To avoid allocating strings (and using a different heavier tt type), our diff --git a/compiler/rustc_errors/src/tests.rs b/compiler/rustc_errors/src/tests.rs index bfe4c9f2a3a..17a1635bd11 100644 --- a/compiler/rustc_errors/src/tests.rs +++ b/compiler/rustc_errors/src/tests.rs @@ -1,11 +1,11 @@ use rustc_data_structures::sync::{IntoDynSyncSend, Lrc}; use rustc_error_messages::fluent_bundle::resolver::errors::{ReferenceKind, ResolverError}; -use rustc_error_messages::{langid, DiagMessage}; +use rustc_error_messages::{DiagMessage, langid}; +use crate::FluentBundle; use crate::error::{TranslateError, TranslateErrorKind}; use crate::fluent_bundle::*; use crate::translation::Translate; -use crate::FluentBundle; struct Dummy { bundle: FluentBundle, |
