diff options
| author | bors <bors@rust-lang.org> | 2023-12-26 02:24:39 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-12-26 02:24:39 +0000 |
| commit | 2271c26e4a8e062bb00d709d0ccb5846e0c341b9 (patch) | |
| tree | a3457e0d9b89710e476158cdaffbddb2b7876c6b /compiler/rustc_errors/src | |
| parent | e4c626dd9a17a23270bf8e7158e59cf2b9c04840 (diff) | |
| parent | 8a9db2545919f945ffbb215e4325917e0bfc5b3a (diff) | |
| download | rust-2271c26e4a8e062bb00d709d0ccb5846e0c341b9.tar.gz rust-2271c26e4a8e062bb00d709d0ccb5846e0c341b9.zip | |
Auto merge of #119146 - nnethercote:rm-DiagCtxt-api-duplication, r=compiler-errors
Remove `DiagCtxt` API duplication `DiagCtxt` defines the internal API for creating and emitting diagnostics: methods like `struct_err`, `struct_span_warn`, `note`, `create_fatal`, `emit_bug`. There are over 50 methods. Some of these methods are then duplicated across several other types: `Session`, `ParseSess`, `Parser`, `ExtCtxt`, and `MirBorrowckCtxt`. `Session` duplicates the most, though half the ones it does are unused. Each duplicated method just calls forward to the corresponding method in `DiagCtxt`. So this duplication exists to (in the best case) shorten chains like `ecx.tcx.sess.parse_sess.dcx.emit_err()` to `ecx.emit_err()`. This API duplication is ugly and has been bugging me for a while. And it's inconsistent: there's no real logic about which methods are duplicated, and the use of `#[rustc_lint_diagnostic]` and `#[track_caller]` attributes vary across the duplicates. This PR removes the duplicated API methods and makes all diagnostic creation and emission go through `DiagCtxt`. It also adds `dcx` getter methods to several types to shorten chains. This approach scales *much* better than API duplication; indeed, the PR adds `dcx()` to numerous types that didn't have API duplication: `TyCtxt`, `LoweringCtxt`, `ConstCx`, `FnCtxt`, `TypeErrCtxt`, `InferCtxt`, `CrateLoader`, `CheckAttrVisitor`, and `Resolver`. These result in a lot of changes from `foo.tcx.sess.emit_err()` to `foo.dcx().emit_err()`. (You could do this with more types, but it gets into diminishing returns territory for types that don't emit many diagnostics.) After all these changes, some call sites are more verbose, some are less verbose, and many are the same. The total number of lines is reduced, mostly because of the removed API duplication. And consistency is increased, because calls to `emit_err` and friends are always preceded with `.dcx()` or `.dcx`. r? `@compiler-errors`
Diffstat (limited to 'compiler/rustc_errors/src')
| -rw-r--r-- | compiler/rustc_errors/src/diagnostic_builder.rs | 4 | ||||
| -rw-r--r-- | compiler/rustc_errors/src/lib.rs | 29 |
2 files changed, 28 insertions, 5 deletions
diff --git a/compiler/rustc_errors/src/diagnostic_builder.rs b/compiler/rustc_errors/src/diagnostic_builder.rs index 4703e71523d..ae54d343dad 100644 --- a/compiler/rustc_errors/src/diagnostic_builder.rs +++ b/compiler/rustc_errors/src/diagnostic_builder.rs @@ -546,8 +546,8 @@ impl<G: EmissionGuarantee> Drop for DiagnosticBuilder<'_, G> { #[macro_export] macro_rules! struct_span_err { - ($session:expr, $span:expr, $code:ident, $($message:tt)*) => ({ - $session.struct_span_err_with_code( + ($dcx:expr, $span:expr, $code:ident, $($message:tt)*) => ({ + $dcx.struct_span_err_with_code( $span, format!($($message)*), $crate::error_code!($code), diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs index 7a1faac04d3..e436591fdd9 100644 --- a/compiler/rustc_errors/src/lib.rs +++ b/compiler/rustc_errors/src/lib.rs @@ -980,10 +980,22 @@ impl DiagCtxt { self.struct_span_bug(span, msg).emit() } - /// For documentation on this, see `Session::span_delayed_bug`. + /// 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). + /// + /// If no span is available, use [`DUMMY_SP`]. + /// + /// [`DUMMY_SP`]: rustc_span::DUMMY_SP /// /// Note: this function used to be called `delay_span_bug`. It was renamed - /// to match similar functions like `span_bug`, `span_err`, etc. + /// to match similar functions like `span_err`, `span_warn`, etc. #[track_caller] pub fn span_delayed_bug( &self, @@ -1203,6 +1215,7 @@ impl DiagCtxt { self.inner.borrow_mut().emit_diagnostic_without_consuming(diagnostic) } + #[track_caller] pub fn emit_err<'a>(&'a self, err: impl IntoDiagnostic<'a>) -> ErrorGuaranteed { self.create_err(err).emit() } @@ -1212,6 +1225,7 @@ impl DiagCtxt { err.into_diagnostic(self, Error { lint: false }) } + #[track_caller] pub fn create_warning<'a>( &'a self, warning: impl IntoDiagnostic<'a, ()>, @@ -1219,10 +1233,12 @@ impl DiagCtxt { warning.into_diagnostic(self, Warning(None)) } + #[track_caller] pub fn emit_warning<'a>(&'a self, warning: impl IntoDiagnostic<'a, ()>) { self.create_warning(warning).emit() } + #[track_caller] pub fn create_almost_fatal<'a>( &'a self, fatal: impl IntoDiagnostic<'a, FatalError>, @@ -1230,6 +1246,7 @@ impl DiagCtxt { fatal.into_diagnostic(self, Fatal) } + #[track_caller] pub fn emit_almost_fatal<'a>( &'a self, fatal: impl IntoDiagnostic<'a, FatalError>, @@ -1237,6 +1254,7 @@ impl DiagCtxt { self.create_almost_fatal(fatal).emit() } + #[track_caller] pub fn create_fatal<'a>( &'a self, fatal: impl IntoDiagnostic<'a, FatalAbort>, @@ -1244,10 +1262,12 @@ impl DiagCtxt { fatal.into_diagnostic(self, Fatal) } + #[track_caller] pub fn emit_fatal<'a>(&'a self, fatal: impl IntoDiagnostic<'a, FatalAbort>) -> ! { self.create_fatal(fatal).emit() } + #[track_caller] pub fn create_bug<'a>( &'a self, bug: impl IntoDiagnostic<'a, BugAbort>, @@ -1255,14 +1275,17 @@ impl DiagCtxt { bug.into_diagnostic(self, Bug) } - pub fn emit_bug<'a>(&'a self, bug: impl IntoDiagnostic<'a, BugAbort>) -> ! { + #[track_caller] + pub fn emit_bug<'a>(&'a self, bug: impl IntoDiagnostic<'a, diagnostic_builder::BugAbort>) -> ! { self.create_bug(bug).emit() } + #[track_caller] pub fn emit_note<'a>(&'a self, note: impl IntoDiagnostic<'a, ()>) { self.create_note(note).emit() } + #[track_caller] pub fn create_note<'a>( &'a self, note: impl IntoDiagnostic<'a, ()>, |
