@@ -289,6 +289,9 @@ pub struct DiagInner {
289
289
pub suggestions : Suggestions ,
290
290
pub args : DiagArgMap ,
291
291
292
+ // This is used to store args and restore them after a subdiagnostic is rendered.
293
+ pub reserved_args : DiagArgMap ,
294
+
292
295
/// This is not used for highlighting or rendering any error message. Rather, it can be used
293
296
/// as a sort key to sort a buffer of diagnostics. By default, it is the primary span of
294
297
/// `span` if there is one. Otherwise, it is `DUMMY_SP`.
@@ -319,6 +322,7 @@ impl DiagInner {
319
322
children : vec ! [ ] ,
320
323
suggestions : Suggestions :: Enabled ( vec ! [ ] ) ,
321
324
args : Default :: default ( ) ,
325
+ reserved_args : Default :: default ( ) ,
322
326
sort_span : DUMMY_SP ,
323
327
is_lint : None ,
324
328
long_ty_path : None ,
@@ -390,7 +394,27 @@ impl DiagInner {
390
394
}
391
395
392
396
pub ( crate ) fn arg ( & mut self , name : impl Into < DiagArgName > , arg : impl IntoDiagArg ) {
393
- self . args . insert ( name. into ( ) , arg. into_diag_arg ( & mut self . long_ty_path ) ) ;
397
+ let name = name. into ( ) ;
398
+ let value = arg. into_diag_arg ( & mut self . long_ty_path ) ;
399
+ // This assertion is to avoid subdiagnostics overwriting an existing diagnostic arg.
400
+ debug_assert ! (
401
+ !self . args. contains_key( & name) || self . args. get( & name) == Some ( & value) ,
402
+ "arg {} already exists" ,
403
+ name
404
+ ) ;
405
+ self . args . insert ( name, value) ;
406
+ }
407
+
408
+ pub fn remove_arg ( & mut self , name : & str ) {
409
+ self . args . swap_remove ( name) ;
410
+ }
411
+
412
+ pub fn store_args ( & mut self ) {
413
+ self . reserved_args = self . args . clone ( ) ;
414
+ }
415
+
416
+ pub fn restore_args ( & mut self ) {
417
+ self . args = std:: mem:: take ( & mut self . reserved_args ) ;
394
418
}
395
419
396
420
/// Fields used for Hash, and PartialEq trait.
@@ -1423,6 +1447,12 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
1423
1447
self . downgrade_to_delayed_bug ( ) ;
1424
1448
self . emit ( )
1425
1449
}
1450
+
1451
+ pub fn remove_arg ( & mut self , name : & str ) {
1452
+ if let Some ( diag) = self . diag . as_mut ( ) {
1453
+ diag. remove_arg ( name) ;
1454
+ }
1455
+ }
1426
1456
}
1427
1457
1428
1458
/// Destructor bomb: every `Diag` must be consumed (emitted, cancelled, etc.)
0 commit comments