@@ -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,28 @@ 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 = self . reserved_args . clone ( ) ;
418
+ self . reserved_args . clear ( ) ;
394
419
}
395
420
396
421
/// Fields used for Hash, and PartialEq trait.
@@ -1423,6 +1448,12 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
1423
1448
self . downgrade_to_delayed_bug ( ) ;
1424
1449
self . emit ( )
1425
1450
}
1451
+
1452
+ pub fn remove_arg ( & mut self , name : & str ) {
1453
+ if let Some ( diag) = self . diag . as_mut ( ) {
1454
+ diag. remove_arg ( name) ;
1455
+ }
1456
+ }
1426
1457
}
1427
1458
1428
1459
/// Destructor bomb: every `Diag` must be consumed (emitted, cancelled, etc.)
0 commit comments