@@ -44,30 +44,15 @@ where
44
44
#[ must_use]
45
45
#[ derive( Clone ) ]
46
46
pub 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 > {
64
47
state : DiagnosticBuilderState < ' a > ,
65
48
66
49
/// `Diagnostic` is a large type, and `DiagnosticBuilder` is often used as a
67
50
/// return value, especially within the frequently-used `PResult` type.
68
51
/// In theory, return value optimization (RVO) should avoid unnecessary
69
52
/// copying. In practice, it does not (at the time of writing).
70
53
diagnostic : Box < Diagnostic > ,
54
+
55
+ _marker : PhantomData < G > ,
71
56
}
72
57
73
58
#[ derive( Clone ) ]
@@ -83,7 +68,7 @@ enum DiagnosticBuilderState<'a> {
83
68
/// assumed that `.emit()` was previously called, to end up in this state.
84
69
///
85
70
/// 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
87
72
/// `self` by-value specifically to prevent any attempts to `.emit()`.
88
73
///
89
74
// FIXME(eddyb) currently this doesn't prevent extending the `Diagnostic`,
@@ -115,47 +100,36 @@ pub trait EmissionGuarantee: Sized {
115
100
impl < ' a , G : EmissionGuarantee > DiagnosticBuilder < ' a , G > {
116
101
/// Most `emit_producing_guarantee` functions use this as a starting point.
117
102
fn emit_producing_nothing ( & mut self ) {
118
- match self . inner . state {
103
+ match self . state {
119
104
// First `.emit()` call, the `&DiagCtxt` is still available.
120
105
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 ) ;
124
108
}
125
109
// `.emit()` was previously called, disallowed from repeating it.
126
110
DiagnosticBuilderState :: AlreadyEmittedOrDuringCancellation => { }
127
111
}
128
112
}
129
113
}
130
114
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
-
140
115
// FIXME(eddyb) make `ErrorGuaranteed` impossible to create outside `.emit()`.
141
116
impl EmissionGuarantee for ErrorGuaranteed {
142
117
fn emit_producing_guarantee ( db : & mut DiagnosticBuilder < ' _ , Self > ) -> Self :: EmitResult {
143
118
// Contrast this with `emit_producing_nothing`.
144
- match db. inner . state {
119
+ match db. state {
145
120
// First `.emit()` call, the `&DiagCtxt` is still available.
146
121
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 ) ;
150
124
151
125
// Only allow a guarantee if the `level` wasn't switched to a
152
126
// non-error - the field isn't `pub`, but the whole `Diagnostic`
153
127
// can be overwritten with a new one, thanks to `DerefMut`.
154
128
assert ! (
155
- db. inner . diagnostic. is_error( ) ,
129
+ db. diagnostic. is_error( ) ,
156
130
"emitted non-error ({:?}) diagnostic \
157
131
from `DiagnosticBuilder<ErrorGuaranteed>`",
158
- db. inner . diagnostic. level,
132
+ db. diagnostic. level,
159
133
) ;
160
134
guar. unwrap ( )
161
135
}
@@ -167,10 +141,10 @@ impl EmissionGuarantee for ErrorGuaranteed {
167
141
// non-error - the field isn't `pub`, but the whole `Diagnostic`
168
142
// can be overwritten with a new one, thanks to `DerefMut`.
169
143
assert ! (
170
- db. inner . diagnostic. is_error( ) ,
144
+ db. diagnostic. is_error( ) ,
171
145
"`DiagnosticBuilder<ErrorGuaranteed>`'s diagnostic \
172
146
became non-error ({:?}), after original `.emit()`",
173
- db. inner . diagnostic. level,
147
+ db. diagnostic. level,
174
148
) ;
175
149
#[ allow( deprecated) ]
176
150
ErrorGuaranteed :: unchecked_claim_error_was_emitted ( )
@@ -238,7 +212,7 @@ macro_rules! forward {
238
212
$( #[ $attrs] ) *
239
213
#[ doc = concat!( "See [`Diagnostic::" , stringify!( $n) , "()`]." ) ]
240
214
pub fn $n( & mut self , $( $name: $ty) ,* ) -> & mut Self {
241
- self . inner . diagnostic. $n( $( $name) ,* ) ;
215
+ self . diagnostic. $n( $( $name) ,* ) ;
242
216
self
243
217
}
244
218
} ;
@@ -248,13 +222,13 @@ impl<G: EmissionGuarantee> Deref for DiagnosticBuilder<'_, G> {
248
222
type Target = Diagnostic ;
249
223
250
224
fn deref ( & self ) -> & Diagnostic {
251
- & self . inner . diagnostic
225
+ & self . diagnostic
252
226
}
253
227
}
254
228
255
229
impl < G : EmissionGuarantee > DerefMut for DiagnosticBuilder < ' _ , G > {
256
230
fn deref_mut ( & mut self ) -> & mut Diagnostic {
257
- & mut self . inner . diagnostic
231
+ & mut self . diagnostic
258
232
}
259
233
}
260
234
@@ -271,10 +245,8 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
271
245
pub ( crate ) fn new_diagnostic ( dcx : & ' a DiagCtxt , diagnostic : Diagnostic ) -> Self {
272
246
debug ! ( "Created new diagnostic" ) ;
273
247
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) ,
278
250
_marker : PhantomData ,
279
251
}
280
252
}
@@ -306,7 +278,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
306
278
/// which may be expected to *guarantee* the emission of an error, either
307
279
/// at the time of the call, or through a prior `.emit()` call.
308
280
pub fn cancel ( mut self ) {
309
- self . inner . state = DiagnosticBuilderState :: AlreadyEmittedOrDuringCancellation ;
281
+ self . state = DiagnosticBuilderState :: AlreadyEmittedOrDuringCancellation ;
310
282
drop ( self ) ;
311
283
}
312
284
@@ -324,7 +296,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
324
296
/// Converts the builder to a `Diagnostic` for later emission,
325
297
/// unless dcx has disabled such buffering, or `.emit()` was called.
326
298
pub fn into_diagnostic ( mut self ) -> Option < ( Diagnostic , & ' a DiagCtxt ) > {
327
- let dcx = match self . inner . state {
299
+ let dcx = match self . state {
328
300
// No `.emit()` calls, the `&DiagCtxt` is still available.
329
301
DiagnosticBuilderState :: Emittable ( dcx) => dcx,
330
302
// `.emit()` was previously called, nothing we can do.
@@ -342,7 +314,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
342
314
343
315
// Take the `Diagnostic` by replacing it with a dummy.
344
316
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) ;
346
318
347
319
// Disable the ICE on `Drop`.
348
320
self . cancel ( ) ;
@@ -356,7 +328,7 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
356
328
357
329
/// Retrieves the [`DiagCtxt`] if available
358
330
pub fn dcx ( & self ) -> Option < & DiagCtxt > {
359
- match self . inner . state {
331
+ match self . state {
360
332
DiagnosticBuilderState :: Emittable ( dcx) => Some ( dcx) ,
361
333
DiagnosticBuilderState :: AlreadyEmittedOrDuringCancellation => None ,
362
334
}
@@ -544,13 +516,13 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
544
516
545
517
impl < G : EmissionGuarantee > Debug for DiagnosticBuilder < ' _ , G > {
546
518
fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
547
- self . inner . diagnostic . fmt ( f)
519
+ self . diagnostic . fmt ( f)
548
520
}
549
521
}
550
522
551
523
/// Destructor bomb - a `DiagnosticBuilder` must be either emitted or cancelled
552
524
/// or we emit a bug.
553
- impl Drop for DiagnosticBuilderInner < ' _ > {
525
+ impl < G : EmissionGuarantee > Drop for DiagnosticBuilder < ' _ , G > {
554
526
fn drop ( & mut self ) {
555
527
match self . state {
556
528
// No `.emit()` or `.cancel()` calls.
0 commit comments