@@ -101,11 +101,15 @@ rustc_data_structures::static_assert_size!(
101101/// Trait for types that `DiagnosticBuilder::emit` can return as a "guarantee"
102102/// (or "proof") token that the emission happened.
103103pub trait EmissionGuarantee : Sized {
104+ /// This exists so that bugs and fatal errors can both result in `!` (an
105+ /// abort) when emitted, but have different aborting behaviour.
106+ type EmitResult = Self ;
107+
104108 /// Implementation of `DiagnosticBuilder::emit`, fully controlled by each
105109 /// `impl` of `EmissionGuarantee`, to make it impossible to create a value
106- /// of `Self` without actually performing the emission.
110+ /// of `Self::EmitResult ` without actually performing the emission.
107111 #[ track_caller]
108- fn diagnostic_builder_emit_producing_guarantee ( db : & mut DiagnosticBuilder < ' _ , Self > ) -> Self ;
112+ fn emit_producing_guarantee ( db : & mut DiagnosticBuilder < ' _ , Self > ) -> Self :: EmitResult ;
109113}
110114
111115impl < ' a > DiagnosticBuilder < ' a , ErrorGuaranteed > {
@@ -119,7 +123,7 @@ impl<'a> DiagnosticBuilder<'a, ErrorGuaranteed> {
119123
120124// FIXME(eddyb) make `ErrorGuaranteed` impossible to create outside `.emit()`.
121125impl EmissionGuarantee for ErrorGuaranteed {
122- fn diagnostic_builder_emit_producing_guarantee ( db : & mut DiagnosticBuilder < ' _ , Self > ) -> Self {
126+ fn emit_producing_guarantee ( db : & mut DiagnosticBuilder < ' _ , Self > ) -> Self :: EmitResult {
123127 match db. inner . state {
124128 // First `.emit()` call, the `&DiagCtxt` is still available.
125129 DiagnosticBuilderState :: Emittable ( dcx) => {
@@ -160,7 +164,7 @@ impl EmissionGuarantee for ErrorGuaranteed {
160164
161165// FIXME(eddyb) should there be a `Option<ErrorGuaranteed>` impl as well?
162166impl EmissionGuarantee for ( ) {
163- fn diagnostic_builder_emit_producing_guarantee ( db : & mut DiagnosticBuilder < ' _ , Self > ) -> Self {
167+ fn emit_producing_guarantee ( db : & mut DiagnosticBuilder < ' _ , Self > ) -> Self :: EmitResult {
164168 match db. inner . state {
165169 // First `.emit()` call, the `&DiagCtxt` is still available.
166170 DiagnosticBuilderState :: Emittable ( dcx) => {
@@ -174,34 +178,15 @@ impl EmissionGuarantee for () {
174178 }
175179}
176180
177- /// Marker type which enables implementation of `create_note` and `emit_note` functions for
178- /// note-without-error struct diagnostics.
179- #[ derive( Copy , Clone ) ]
180- pub struct Noted ;
181-
182- impl EmissionGuarantee for Noted {
183- fn diagnostic_builder_emit_producing_guarantee ( db : & mut DiagnosticBuilder < ' _ , Self > ) -> Self {
184- match db. inner . state {
185- // First `.emit()` call, the `&DiagCtxt` is still available.
186- DiagnosticBuilderState :: Emittable ( dcx) => {
187- db. inner . state = DiagnosticBuilderState :: AlreadyEmittedOrDuringCancellation ;
188- dcx. emit_diagnostic_without_consuming ( & mut db. inner . diagnostic ) ;
189- }
190- // `.emit()` was previously called, disallowed from repeating it.
191- DiagnosticBuilderState :: AlreadyEmittedOrDuringCancellation => { }
192- }
193-
194- Noted
195- }
196- }
197-
198181/// Marker type which enables implementation of `create_bug` and `emit_bug` functions for
199- /// bug struct diagnostics.
182+ /// bug diagnostics.
200183#[ derive( Copy , Clone ) ]
201- pub struct Bug ;
184+ pub struct BugAbort ;
185+
186+ impl EmissionGuarantee for BugAbort {
187+ type EmitResult = !;
202188
203- impl EmissionGuarantee for Bug {
204- fn diagnostic_builder_emit_producing_guarantee ( db : & mut DiagnosticBuilder < ' _ , Self > ) -> Self {
189+ fn emit_producing_guarantee ( db : & mut DiagnosticBuilder < ' _ , Self > ) -> Self :: EmitResult {
205190 match db. inner . state {
206191 // First `.emit()` call, the `&DiagCtxt` is still available.
207192 DiagnosticBuilderState :: Emittable ( dcx) => {
@@ -217,8 +202,15 @@ impl EmissionGuarantee for Bug {
217202 }
218203}
219204
220- impl EmissionGuarantee for ! {
221- fn diagnostic_builder_emit_producing_guarantee ( db : & mut DiagnosticBuilder < ' _ , Self > ) -> Self {
205+ /// Marker type which enables implementation of `create_fatal` and `emit_fatal` functions for
206+ /// fatal diagnostics.
207+ #[ derive( Copy , Clone ) ]
208+ pub struct FatalAbort ;
209+
210+ impl EmissionGuarantee for FatalAbort {
211+ type EmitResult = !;
212+
213+ fn emit_producing_guarantee ( db : & mut DiagnosticBuilder < ' _ , Self > ) -> Self :: EmitResult {
222214 match db. inner . state {
223215 // First `.emit()` call, the `&DiagCtxt` is still available.
224216 DiagnosticBuilderState :: Emittable ( dcx) => {
@@ -235,7 +227,7 @@ impl EmissionGuarantee for ! {
235227}
236228
237229impl EmissionGuarantee for rustc_span:: fatal_error:: FatalError {
238- fn diagnostic_builder_emit_producing_guarantee ( db : & mut DiagnosticBuilder < ' _ , Self > ) -> Self {
230+ fn emit_producing_guarantee ( db : & mut DiagnosticBuilder < ' _ , Self > ) -> Self :: EmitResult {
239231 match db. inner . state {
240232 // First `.emit()` call, the `&DiagCtxt` is still available.
241233 DiagnosticBuilderState :: Emittable ( dcx) => {
@@ -313,16 +305,16 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
313305 /// but there are various places that rely on continuing to use `self`
314306 /// after calling `emit`.
315307 #[ track_caller]
316- pub fn emit ( & mut self ) -> G {
317- G :: diagnostic_builder_emit_producing_guarantee ( self )
308+ pub fn emit ( & mut self ) -> G :: EmitResult {
309+ G :: emit_producing_guarantee ( self )
318310 }
319311
320312 /// Emit the diagnostic unless `delay` is true,
321313 /// in which case the emission will be delayed as a bug.
322314 ///
323315 /// See `emit` and `delay_as_bug` for details.
324316 #[ track_caller]
325- pub fn emit_unless ( & mut self , delay : bool ) -> G {
317+ pub fn emit_unless ( & mut self , delay : bool ) -> G :: EmitResult {
326318 if delay {
327319 self . downgrade_to_delayed_bug ( ) ;
328320 }
@@ -409,7 +401,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
409401 /// In the meantime, though, callsites are required to deal with the "bug"
410402 /// locally in whichever way makes the most sense.
411403 #[ track_caller]
412- pub fn delay_as_bug ( & mut self ) -> G {
404+ pub fn delay_as_bug ( & mut self ) -> G :: EmitResult {
413405 self . downgrade_to_delayed_bug ( ) ;
414406 self . emit ( )
415407 }
0 commit comments