@@ -44,30 +44,15 @@ where
4444#[ must_use]
4545#[ derive( Clone ) ]
4646pub struct DiagnosticBuilder < ' a , G : EmissionGuarantee = ErrorGuaranteed > {
47- inner : DiagnosticBuilderInner < ' a > ,
48- _marker : PhantomData < G > ,
49- }
50-
51- /// This type exists only for `DiagnosticBuilder::forget_guarantee`, because it:
52- /// 1. lacks the `G` parameter and therefore `DiagnosticBuilder<G1>` can be
53- /// converted into `DiagnosticBuilder<G2>` while reusing the `inner` field
54- /// 2. can implement the `Drop` "bomb" instead of `DiagnosticBuilder`, as it
55- /// contains all of the data (`state` + `diagnostic`) of `DiagnosticBuilder`
56- ///
57- /// The `diagnostic` field is not `Copy` and can't be moved out of whichever
58- /// type implements the `Drop` "bomb", but because of the above two facts, that
59- /// never needs to happen - instead, the whole `inner: DiagnosticBuilderInner`
60- /// can be moved out of a `DiagnosticBuilder` and into another.
61- #[ must_use]
62- #[ derive( Clone ) ]
63- struct DiagnosticBuilderInner < ' a > {
6447 state : DiagnosticBuilderState < ' a > ,
6548
6649 /// `Diagnostic` is a large type, and `DiagnosticBuilder` is often used as a
6750 /// return value, especially within the frequently-used `PResult` type.
6851 /// In theory, return value optimization (RVO) should avoid unnecessary
6952 /// copying. In practice, it does not (at the time of writing).
7053 diagnostic : Box < Diagnostic > ,
54+
55+ _marker : PhantomData < G > ,
7156}
7257
7358#[ derive( Clone ) ]
@@ -83,7 +68,7 @@ enum DiagnosticBuilderState<'a> {
8368 /// assumed that `.emit()` was previously called, to end up in this state.
8469 ///
8570 /// While this is also used by `.cancel()`, this state is only observed by
86- /// the `Drop` `impl` of `DiagnosticBuilderInner `, as `.cancel()` takes
71+ /// the `Drop` `impl` of `DiagnosticBuilder `, because `.cancel()` takes
8772 /// `self` by-value specifically to prevent any attempts to `.emit()`.
8873 ///
8974 // FIXME(eddyb) currently this doesn't prevent extending the `Diagnostic`,
@@ -115,47 +100,36 @@ pub trait EmissionGuarantee: Sized {
115100impl < ' a , G : EmissionGuarantee > DiagnosticBuilder < ' a , G > {
116101 /// Most `emit_producing_guarantee` functions use this as a starting point.
117102 fn emit_producing_nothing ( & mut self ) {
118- match self . inner . state {
103+ match self . state {
119104 // First `.emit()` call, the `&DiagCtxt` is still available.
120105 DiagnosticBuilderState :: Emittable ( dcx) => {
121- self . inner . state = DiagnosticBuilderState :: AlreadyEmittedOrDuringCancellation ;
122-
123- dcx. emit_diagnostic_without_consuming ( & mut self . inner . diagnostic ) ;
106+ self . state = DiagnosticBuilderState :: AlreadyEmittedOrDuringCancellation ;
107+ dcx. emit_diagnostic_without_consuming ( & mut self . diagnostic ) ;
124108 }
125109 // `.emit()` was previously called, disallowed from repeating it.
126110 DiagnosticBuilderState :: AlreadyEmittedOrDuringCancellation => { }
127111 }
128112 }
129113}
130114
131- impl < ' a > DiagnosticBuilder < ' a > {
132- /// Discard the guarantee `.emit()` would return, in favor of having the
133- /// type `DiagnosticBuilder<'a, ()>`. This may be necessary whenever there
134- /// is a common codepath handling both errors and warnings.
135- pub fn forget_guarantee ( self ) -> DiagnosticBuilder < ' a , ( ) > {
136- DiagnosticBuilder { inner : self . inner , _marker : PhantomData }
137- }
138- }
139-
140115// FIXME(eddyb) make `ErrorGuaranteed` impossible to create outside `.emit()`.
141116impl EmissionGuarantee for ErrorGuaranteed {
142117 fn emit_producing_guarantee ( db : & mut DiagnosticBuilder < ' _ , Self > ) -> Self :: EmitResult {
143118 // Contrast this with `emit_producing_nothing`.
144- match db. inner . state {
119+ match db. state {
145120 // First `.emit()` call, the `&DiagCtxt` is still available.
146121 DiagnosticBuilderState :: Emittable ( dcx) => {
147- db. inner . state = DiagnosticBuilderState :: AlreadyEmittedOrDuringCancellation ;
148-
149- let guar = dcx. emit_diagnostic_without_consuming ( & mut db. inner . diagnostic ) ;
122+ db. state = DiagnosticBuilderState :: AlreadyEmittedOrDuringCancellation ;
123+ let guar = dcx. emit_diagnostic_without_consuming ( & mut db. diagnostic ) ;
150124
151125 // Only allow a guarantee if the `level` wasn't switched to a
152126 // non-error - the field isn't `pub`, but the whole `Diagnostic`
153127 // can be overwritten with a new one, thanks to `DerefMut`.
154128 assert ! (
155- db. inner . diagnostic. is_error( ) ,
129+ db. diagnostic. is_error( ) ,
156130 "emitted non-error ({:?}) diagnostic \
157131 from `DiagnosticBuilder<ErrorGuaranteed>`",
158- db. inner . diagnostic. level,
132+ db. diagnostic. level,
159133 ) ;
160134 guar. unwrap ( )
161135 }
@@ -167,10 +141,10 @@ impl EmissionGuarantee for ErrorGuaranteed {
167141 // non-error - the field isn't `pub`, but the whole `Diagnostic`
168142 // can be overwritten with a new one, thanks to `DerefMut`.
169143 assert ! (
170- db. inner . diagnostic. is_error( ) ,
144+ db. diagnostic. is_error( ) ,
171145 "`DiagnosticBuilder<ErrorGuaranteed>`'s diagnostic \
172146 became non-error ({:?}), after original `.emit()`",
173- db. inner . diagnostic. level,
147+ db. diagnostic. level,
174148 ) ;
175149 #[ allow( deprecated) ]
176150 ErrorGuaranteed :: unchecked_claim_error_was_emitted ( )
@@ -238,7 +212,7 @@ macro_rules! forward {
238212 $( #[ $attrs] ) *
239213 #[ doc = concat!( "See [`Diagnostic::" , stringify!( $n) , "()`]." ) ]
240214 pub fn $n( & mut self , $( $name: $ty) ,* ) -> & mut Self {
241- self . inner . diagnostic. $n( $( $name) ,* ) ;
215+ self . diagnostic. $n( $( $name) ,* ) ;
242216 self
243217 }
244218 } ;
@@ -248,13 +222,13 @@ impl<G: EmissionGuarantee> Deref for DiagnosticBuilder<'_, G> {
248222 type Target = Diagnostic ;
249223
250224 fn deref ( & self ) -> & Diagnostic {
251- & self . inner . diagnostic
225+ & self . diagnostic
252226 }
253227}
254228
255229impl < G : EmissionGuarantee > DerefMut for DiagnosticBuilder < ' _ , G > {
256230 fn deref_mut ( & mut self ) -> & mut Diagnostic {
257- & mut self . inner . diagnostic
231+ & mut self . diagnostic
258232 }
259233}
260234
@@ -271,10 +245,8 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
271245 pub ( crate ) fn new_diagnostic ( dcx : & ' a DiagCtxt , diagnostic : Diagnostic ) -> Self {
272246 debug ! ( "Created new diagnostic" ) ;
273247 Self {
274- inner : DiagnosticBuilderInner {
275- state : DiagnosticBuilderState :: Emittable ( dcx) ,
276- diagnostic : Box :: new ( diagnostic) ,
277- } ,
248+ state : DiagnosticBuilderState :: Emittable ( dcx) ,
249+ diagnostic : Box :: new ( diagnostic) ,
278250 _marker : PhantomData ,
279251 }
280252 }
@@ -306,7 +278,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
306278 /// which may be expected to *guarantee* the emission of an error, either
307279 /// at the time of the call, or through a prior `.emit()` call.
308280 pub fn cancel ( mut self ) {
309- self . inner . state = DiagnosticBuilderState :: AlreadyEmittedOrDuringCancellation ;
281+ self . state = DiagnosticBuilderState :: AlreadyEmittedOrDuringCancellation ;
310282 drop ( self ) ;
311283 }
312284
@@ -324,7 +296,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
324296 /// Converts the builder to a `Diagnostic` for later emission,
325297 /// unless dcx has disabled such buffering, or `.emit()` was called.
326298 pub fn into_diagnostic ( mut self ) -> Option < ( Diagnostic , & ' a DiagCtxt ) > {
327- let dcx = match self . inner . state {
299+ let dcx = match self . state {
328300 // No `.emit()` calls, the `&DiagCtxt` is still available.
329301 DiagnosticBuilderState :: Emittable ( dcx) => dcx,
330302 // `.emit()` was previously called, nothing we can do.
@@ -342,7 +314,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
342314
343315 // Take the `Diagnostic` by replacing it with a dummy.
344316 let dummy = Diagnostic :: new ( Level :: Allow , DiagnosticMessage :: from ( "" ) ) ;
345- let diagnostic = std:: mem:: replace ( & mut * self . inner . diagnostic , dummy) ;
317+ let diagnostic = std:: mem:: replace ( & mut * self . diagnostic , dummy) ;
346318
347319 // Disable the ICE on `Drop`.
348320 self . cancel ( ) ;
@@ -356,7 +328,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
356328
357329 /// Retrieves the [`DiagCtxt`] if available
358330 pub fn dcx ( & self ) -> Option < & DiagCtxt > {
359- match self . inner . state {
331+ match self . state {
360332 DiagnosticBuilderState :: Emittable ( dcx) => Some ( dcx) ,
361333 DiagnosticBuilderState :: AlreadyEmittedOrDuringCancellation => None ,
362334 }
@@ -544,13 +516,13 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
544516
545517impl < G : EmissionGuarantee > Debug for DiagnosticBuilder < ' _ , G > {
546518 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
547- self . inner . diagnostic . fmt ( f)
519+ self . diagnostic . fmt ( f)
548520 }
549521}
550522
551523/// Destructor bomb - a `DiagnosticBuilder` must be either emitted or cancelled
552524/// or we emit a bug.
553- impl Drop for DiagnosticBuilderInner < ' _ > {
525+ impl < G : EmissionGuarantee > Drop for DiagnosticBuilder < ' _ , G > {
554526 fn drop ( & mut self ) {
555527 match self . state {
556528 // No `.emit()` or `.cancel()` calls.
0 commit comments