diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index f503f2e9a540d..5539d40c9eb0d 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -716,216 +716,6 @@ impl DiagCtxt { self.inner.borrow_mut().emit_stashed_diagnostics() } - /// Construct a builder at the `Warning` level at the given `span` and with the `msg`. - /// - /// An `emit` call on the builder will only emit if `can_emit_warnings` is `true`. - #[rustc_lint_diagnostics] - #[track_caller] - pub fn struct_span_warn( - &self, - span: impl Into, - msg: impl Into, - ) -> DiagnosticBuilder<'_, ()> { - self.struct_warn(msg).with_span(span) - } - - /// Construct a builder at the `Warning` level with the `msg`. - /// - /// An `emit` call on the builder will only emit if `can_emit_warnings` is `true`. - #[rustc_lint_diagnostics] - #[track_caller] - pub fn struct_warn(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { - DiagnosticBuilder::new(self, Warning, msg) - } - - /// Construct a builder at the `Allow` level with the `msg`. - #[rustc_lint_diagnostics] - #[track_caller] - pub fn struct_allow(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { - DiagnosticBuilder::new(self, Allow, msg) - } - - /// Construct a builder at the `Expect` level with the `msg`. - #[rustc_lint_diagnostics] - #[track_caller] - pub fn struct_expect( - &self, - msg: impl Into, - id: LintExpectationId, - ) -> DiagnosticBuilder<'_, ()> { - DiagnosticBuilder::new(self, Expect(id), msg) - } - - /// Construct a builder at the `Error` level at the given `span` and with the `msg`. - #[rustc_lint_diagnostics] - #[track_caller] - pub fn struct_span_err( - &self, - span: impl Into, - msg: impl Into, - ) -> DiagnosticBuilder<'_> { - self.struct_err(msg).with_span(span) - } - - /// Construct a builder at the `Error` level with the `msg`. - // FIXME: This method should be removed (every error should have an associated error code). - #[rustc_lint_diagnostics] - #[track_caller] - pub fn struct_err(&self, msg: impl Into) -> DiagnosticBuilder<'_> { - DiagnosticBuilder::new(self, Error, msg) - } - - /// Construct a builder at the `Fatal` level at the given `span` and with the `msg`. - #[rustc_lint_diagnostics] - #[track_caller] - pub fn struct_span_fatal( - &self, - span: impl Into, - msg: impl Into, - ) -> DiagnosticBuilder<'_, FatalAbort> { - self.struct_fatal(msg).with_span(span) - } - - /// Construct a builder at the `Fatal` level with the `msg`. - #[rustc_lint_diagnostics] - #[track_caller] - pub fn struct_fatal( - &self, - msg: impl Into, - ) -> DiagnosticBuilder<'_, FatalAbort> { - DiagnosticBuilder::new(self, Fatal, msg) - } - - /// Construct a builder at the `Help` level with the `msg`. - #[rustc_lint_diagnostics] - pub fn struct_help(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { - DiagnosticBuilder::new(self, Help, msg) - } - - /// Construct a builder at the `Note` level with the `msg`. - #[rustc_lint_diagnostics] - #[track_caller] - pub fn struct_note(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { - DiagnosticBuilder::new(self, Note, msg) - } - - /// Construct a builder at the `Bug` level with the `msg`. - #[rustc_lint_diagnostics] - #[track_caller] - pub fn struct_bug(&self, msg: impl Into) -> DiagnosticBuilder<'_, BugAbort> { - DiagnosticBuilder::new(self, Bug, msg) - } - - /// Construct a builder at the `Bug` level at the given `span` with the `msg`. - #[rustc_lint_diagnostics] - #[track_caller] - pub fn struct_span_bug( - &self, - span: impl Into, - msg: impl Into, - ) -> DiagnosticBuilder<'_, BugAbort> { - self.struct_bug(msg).with_span(span) - } - - #[rustc_lint_diagnostics] - #[track_caller] - pub fn span_fatal(&self, span: impl Into, msg: impl Into) -> ! { - self.struct_span_fatal(span, msg).emit() - } - - #[rustc_lint_diagnostics] - #[track_caller] - pub fn span_err( - &self, - span: impl Into, - msg: impl Into, - ) -> ErrorGuaranteed { - self.struct_span_err(span, msg).emit() - } - - #[rustc_lint_diagnostics] - #[track_caller] - pub fn span_warn(&self, span: impl Into, msg: impl Into) { - self.struct_span_warn(span, msg).emit() - } - - pub fn span_bug(&self, span: impl Into, msg: impl Into) -> ! { - self.struct_span_bug(span, msg).emit() - } - - /// Ensures that compilation cannot succeed. - /// - /// If this function has been called but no errors have been emitted and - /// compilation succeeds, it will cause an internal compiler error (ICE). - /// - /// This can be used in code paths that should never run on successful compilations. - /// For example, it can be used to create an [`ErrorGuaranteed`] - /// (but you should prefer threading through the [`ErrorGuaranteed`] from an error emission - /// directly). - #[track_caller] - pub fn delayed_bug(&self, msg: impl Into) -> ErrorGuaranteed { - DiagnosticBuilder::::new(self, DelayedBug, msg).emit() - } - - /// Like `delayed_bug`, but takes an additional span. - /// - /// Note: this function used to be called `delay_span_bug`. It was renamed - /// to match similar functions like `span_err`, `span_warn`, etc. - #[track_caller] - pub fn span_delayed_bug( - &self, - sp: impl Into, - msg: impl Into, - ) -> ErrorGuaranteed { - DiagnosticBuilder::::new(self, DelayedBug, msg).with_span(sp).emit() - } - - /// Ensures that a diagnostic is printed. See `Level::GoodPathDelayedBug`. - pub fn good_path_delayed_bug(&self, msg: impl Into) { - DiagnosticBuilder::<()>::new(self, GoodPathDelayedBug, msg).emit() - } - - #[track_caller] - #[rustc_lint_diagnostics] - pub fn span_note(&self, span: impl Into, msg: impl Into) { - self.struct_span_note(span, msg).emit() - } - - #[track_caller] - #[rustc_lint_diagnostics] - pub fn struct_span_note( - &self, - span: impl Into, - msg: impl Into, - ) -> DiagnosticBuilder<'_, ()> { - DiagnosticBuilder::new(self, Note, msg).with_span(span) - } - - #[rustc_lint_diagnostics] - pub fn fatal(&self, msg: impl Into) -> ! { - self.struct_fatal(msg).emit() - } - - #[rustc_lint_diagnostics] - pub fn err(&self, msg: impl Into) -> ErrorGuaranteed { - self.struct_err(msg).emit() - } - - #[rustc_lint_diagnostics] - pub fn warn(&self, msg: impl Into) { - self.struct_warn(msg).emit() - } - - #[rustc_lint_diagnostics] - pub fn note(&self, msg: impl Into) { - self.struct_note(msg).emit() - } - - #[rustc_lint_diagnostics] - pub fn bug(&self, msg: impl Into) -> ! { - self.struct_bug(msg).emit() - } - /// This excludes lint errors and delayed bugs. #[inline] pub fn err_count(&self) -> usize { @@ -1065,56 +855,111 @@ impl DiagCtxt { self.inner.borrow_mut().emit_diagnostic(diagnostic) } - #[track_caller] - pub fn emit_err<'a>(&'a self, err: impl IntoDiagnostic<'a>) -> ErrorGuaranteed { - self.create_err(err).emit() + pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) { + self.inner.borrow_mut().emitter.emit_artifact_notification(path, artifact_type); } - #[track_caller] - pub fn create_err<'a>(&'a self, err: impl IntoDiagnostic<'a>) -> DiagnosticBuilder<'a> { - err.into_diagnostic(self, Error) + 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); + } } - #[track_caller] - pub fn create_warn<'a>( - &'a self, - warning: impl IntoDiagnostic<'a, ()>, - ) -> DiagnosticBuilder<'a, ()> { - warning.into_diagnostic(self, Warning) - } + pub fn emit_unused_externs( + &self, + lint_level: rustc_lint_defs::Level, + loud: bool, + unused_externs: &[&str], + ) { + let mut inner = self.inner.borrow_mut(); - #[track_caller] - pub fn emit_warn<'a>(&'a self, warning: impl IntoDiagnostic<'a, ()>) { - self.create_warn(warning).emit() - } + if loud && lint_level.is_error() { + inner.lint_err_count += 1; + inner.panic_if_treat_err_as_bug(); + } - #[track_caller] - pub fn create_almost_fatal<'a>( - &'a self, - fatal: impl IntoDiagnostic<'a, FatalError>, - ) -> DiagnosticBuilder<'a, FatalError> { - fatal.into_diagnostic(self, Fatal) + inner.emitter.emit_unused_externs(lint_level, unused_externs) } - #[track_caller] - pub fn emit_almost_fatal<'a>( - &'a self, - fatal: impl IntoDiagnostic<'a, FatalError>, - ) -> FatalError { - self.create_almost_fatal(fatal).emit() - } + pub fn update_unstable_expectation_id( + &self, + unstable_to_stable: &FxIndexMap, + ) { + let mut inner = self.inner.borrow_mut(); + let diags = std::mem::take(&mut inner.unstable_expect_diagnostics); + inner.check_unstable_expect_diagnostics = true; - #[track_caller] - pub fn create_fatal<'a>( - &'a self, - fatal: impl IntoDiagnostic<'a, FatalAbort>, - ) -> DiagnosticBuilder<'a, FatalAbort> { - fatal.into_diagnostic(self, Fatal) - } + 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); + } + } + + inner + .stashed_diagnostics + .values_mut() + .for_each(|diag| 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 { + assert!( + self.inner.borrow().unstable_expect_diagnostics.is_empty(), + "`DiagCtxtInner::unstable_expect_diagnostics` should be empty at this point", + ); + std::mem::take(&mut self.inner.borrow_mut().fulfilled_expectations) + } + + pub fn flush_delayed(&self) { + self.inner.borrow_mut().flush_delayed(DelayedBugKind::Normal); + } +} + +// This `impl` block contains only the public diagnostic creation/emission API. +// +// Functions beginning with `struct_`/`create_` create a diagnostic. Other +// functions create and emit a diagnostic all in one go. +impl DiagCtxt { + // No `#[rustc_lint_diagnostics]` because bug messages aren't user-facing. #[track_caller] - pub fn emit_fatal<'a>(&'a self, fatal: impl IntoDiagnostic<'a, FatalAbort>) -> ! { - self.create_fatal(fatal).emit() + pub fn struct_bug(&self, msg: impl Into) -> DiagnosticBuilder<'_, BugAbort> { + DiagnosticBuilder::new(self, Bug, msg) + } + + // No `#[rustc_lint_diagnostics]` because bug messages aren't user-facing. + #[track_caller] + pub fn bug(&self, msg: impl Into) -> ! { + self.struct_bug(msg).emit() + } + + // No `#[rustc_lint_diagnostics]` because bug messages aren't user-facing. + #[track_caller] + pub fn struct_span_bug( + &self, + span: impl Into, + msg: impl Into, + ) -> DiagnosticBuilder<'_, BugAbort> { + self.struct_bug(msg).with_span(span) + } + + // No `#[rustc_lint_diagnostics]` because bug messages aren't user-facing. + #[track_caller] + pub fn span_bug(&self, span: impl Into, msg: impl Into) -> ! { + self.struct_span_bug(span, msg).emit() } #[track_caller] @@ -1126,94 +971,243 @@ impl DiagCtxt { } #[track_caller] - pub fn emit_bug<'a>(&'a self, bug: impl IntoDiagnostic<'a, diagnostic_builder::BugAbort>) -> ! { + pub fn emit_bug<'a>(&'a self, bug: impl IntoDiagnostic<'a, BugAbort>) -> ! { self.create_bug(bug).emit() } + #[rustc_lint_diagnostics] #[track_caller] - pub fn emit_note<'a>(&'a self, note: impl IntoDiagnostic<'a, ()>) { - self.create_note(note).emit() + pub fn struct_fatal( + &self, + msg: impl Into, + ) -> DiagnosticBuilder<'_, FatalAbort> { + DiagnosticBuilder::new(self, Fatal, msg) } + #[rustc_lint_diagnostics] #[track_caller] - pub fn create_note<'a>( + pub fn fatal(&self, msg: impl Into) -> ! { + self.struct_fatal(msg).emit() + } + + #[rustc_lint_diagnostics] + #[track_caller] + pub fn struct_span_fatal( + &self, + span: impl Into, + msg: impl Into, + ) -> DiagnosticBuilder<'_, FatalAbort> { + self.struct_fatal(msg).with_span(span) + } + + #[rustc_lint_diagnostics] + #[track_caller] + pub fn span_fatal(&self, span: impl Into, msg: impl Into) -> ! { + self.struct_span_fatal(span, msg).emit() + } + + #[track_caller] + pub fn create_fatal<'a>( &'a self, - note: impl IntoDiagnostic<'a, ()>, - ) -> DiagnosticBuilder<'a, ()> { - note.into_diagnostic(self, Note) + fatal: impl IntoDiagnostic<'a, FatalAbort>, + ) -> DiagnosticBuilder<'a, FatalAbort> { + fatal.into_diagnostic(self, Fatal) } - pub fn emit_artifact_notification(&self, path: &Path, artifact_type: &str) { - self.inner.borrow_mut().emitter.emit_artifact_notification(path, artifact_type); + #[track_caller] + pub fn emit_fatal<'a>(&'a self, fatal: impl IntoDiagnostic<'a, FatalAbort>) -> ! { + self.create_fatal(fatal).emit() } - 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); - } + #[track_caller] + pub fn create_almost_fatal<'a>( + &'a self, + fatal: impl IntoDiagnostic<'a, FatalError>, + ) -> DiagnosticBuilder<'a, FatalError> { + fatal.into_diagnostic(self, Fatal) } - pub fn emit_unused_externs( + #[track_caller] + pub fn emit_almost_fatal<'a>( + &'a self, + fatal: impl IntoDiagnostic<'a, FatalError>, + ) -> FatalError { + self.create_almost_fatal(fatal).emit() + } + + // FIXME: This method should be removed (every error should have an associated error code). + #[rustc_lint_diagnostics] + #[track_caller] + pub fn struct_err(&self, msg: impl Into) -> DiagnosticBuilder<'_> { + DiagnosticBuilder::new(self, Error, msg) + } + + #[rustc_lint_diagnostics] + #[track_caller] + pub fn err(&self, msg: impl Into) -> ErrorGuaranteed { + self.struct_err(msg).emit() + } + + #[rustc_lint_diagnostics] + #[track_caller] + pub fn struct_span_err( &self, - lint_level: rustc_lint_defs::Level, - loud: bool, - unused_externs: &[&str], - ) { - let mut inner = self.inner.borrow_mut(); + span: impl Into, + msg: impl Into, + ) -> DiagnosticBuilder<'_> { + self.struct_err(msg).with_span(span) + } - if loud && lint_level.is_error() { - inner.lint_err_count += 1; - inner.panic_if_treat_err_as_bug(); - } + #[rustc_lint_diagnostics] + #[track_caller] + pub fn span_err( + &self, + span: impl Into, + msg: impl Into, + ) -> ErrorGuaranteed { + self.struct_span_err(span, msg).emit() + } - inner.emitter.emit_unused_externs(lint_level, unused_externs) + #[track_caller] + pub fn create_err<'a>(&'a self, err: impl IntoDiagnostic<'a>) -> DiagnosticBuilder<'a> { + err.into_diagnostic(self, Error) } - pub fn update_unstable_expectation_id( + #[track_caller] + pub fn emit_err<'a>(&'a self, err: impl IntoDiagnostic<'a>) -> ErrorGuaranteed { + self.create_err(err).emit() + } + + /// Ensures that an error is printed. See `Level::DelayedBug`. + // No `#[rustc_lint_diagnostics]` because bug messages aren't user-facing. + #[track_caller] + pub fn delayed_bug(&self, msg: impl Into) -> ErrorGuaranteed { + DiagnosticBuilder::::new(self, DelayedBug, msg).emit() + } + + /// Ensures that an error is printed. See `Level::DelayedBug`. + /// + /// Note: this function used to be called `delay_span_bug`. It was renamed + /// to match similar functions like `span_err`, `span_warn`, etc. + // No `#[rustc_lint_diagnostics]` because bug messages aren't user-facing. + #[track_caller] + pub fn span_delayed_bug( &self, - unstable_to_stable: &FxIndexMap, - ) { - let mut inner = self.inner.borrow_mut(); - let diags = std::mem::take(&mut inner.unstable_expect_diagnostics); - inner.check_unstable_expect_diagnostics = true; + sp: impl Into, + msg: impl Into, + ) -> ErrorGuaranteed { + DiagnosticBuilder::::new(self, DelayedBug, msg).with_span(sp).emit() + } - if !diags.is_empty() { - inner.suppressed_expected_diag = true; - for mut diag in diags.into_iter() { - diag.update_unstable_expectation_id(unstable_to_stable); + /// Ensures that a diagnostic is printed. See `Level::GoodPathDelayedBug`. + // No `#[rustc_lint_diagnostics]` because bug messages aren't user-facing. + #[track_caller] + pub fn good_path_delayed_bug(&self, msg: impl Into) { + DiagnosticBuilder::<()>::new(self, GoodPathDelayedBug, msg).emit() + } - // 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); - } - } + #[rustc_lint_diagnostics] + #[track_caller] + pub fn struct_warn(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { + DiagnosticBuilder::new(self, Warning, msg) + } - inner - .stashed_diagnostics - .values_mut() - .for_each(|diag| 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)); + #[rustc_lint_diagnostics] + #[track_caller] + pub fn warn(&self, msg: impl Into) { + self.struct_warn(msg).emit() } - /// 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 { - assert!( - self.inner.borrow().unstable_expect_diagnostics.is_empty(), - "`DiagCtxtInner::unstable_expect_diagnostics` should be empty at this point", - ); - std::mem::take(&mut self.inner.borrow_mut().fulfilled_expectations) + #[rustc_lint_diagnostics] + #[track_caller] + pub fn struct_span_warn( + &self, + span: impl Into, + msg: impl Into, + ) -> DiagnosticBuilder<'_, ()> { + self.struct_warn(msg).with_span(span) } - pub fn flush_delayed(&self) { - self.inner.borrow_mut().flush_delayed(DelayedBugKind::Normal); + #[rustc_lint_diagnostics] + #[track_caller] + pub fn span_warn(&self, span: impl Into, msg: impl Into) { + self.struct_span_warn(span, msg).emit() + } + + #[track_caller] + pub fn create_warn<'a>( + &'a self, + warning: impl IntoDiagnostic<'a, ()>, + ) -> DiagnosticBuilder<'a, ()> { + warning.into_diagnostic(self, Warning) + } + + #[track_caller] + pub fn emit_warn<'a>(&'a self, warning: impl IntoDiagnostic<'a, ()>) { + self.create_warn(warning).emit() + } + + #[rustc_lint_diagnostics] + #[track_caller] + pub fn struct_note(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { + DiagnosticBuilder::new(self, Note, msg) + } + + #[rustc_lint_diagnostics] + #[track_caller] + pub fn note(&self, msg: impl Into) { + self.struct_note(msg).emit() + } + + #[rustc_lint_diagnostics] + #[track_caller] + pub fn struct_span_note( + &self, + span: impl Into, + msg: impl Into, + ) -> DiagnosticBuilder<'_, ()> { + DiagnosticBuilder::new(self, Note, msg).with_span(span) + } + + #[rustc_lint_diagnostics] + #[track_caller] + pub fn span_note(&self, span: impl Into, msg: impl Into) { + self.struct_span_note(span, msg).emit() + } + + #[track_caller] + pub fn create_note<'a>( + &'a self, + note: impl IntoDiagnostic<'a, ()>, + ) -> DiagnosticBuilder<'a, ()> { + note.into_diagnostic(self, Note) + } + + #[track_caller] + pub fn emit_note<'a>(&'a self, note: impl IntoDiagnostic<'a, ()>) { + self.create_note(note).emit() + } + + #[rustc_lint_diagnostics] + #[track_caller] + pub fn struct_help(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { + DiagnosticBuilder::new(self, Help, msg) + } + + #[rustc_lint_diagnostics] + #[track_caller] + pub fn struct_allow(&self, msg: impl Into) -> DiagnosticBuilder<'_, ()> { + DiagnosticBuilder::new(self, Allow, msg) + } + + #[rustc_lint_diagnostics] + #[track_caller] + pub fn struct_expect( + &self, + msg: impl Into, + id: LintExpectationId, + ) -> DiagnosticBuilder<'_, ()> { + DiagnosticBuilder::new(self, Expect(id), msg) } } @@ -1574,6 +1568,7 @@ pub enum Level { ForceWarning(Option), /// A warning about the code being compiled. Does not prevent compilation from finishing. + /// Will be skipped if `can_emit_warnings` is false. Warning, /// A message giving additional context.