@@ -289,6 +289,9 @@ pub struct DiagInner {
289289 pub suggestions : Suggestions ,
290290 pub args : DiagArgMap ,
291291
292+ // This is used to store args and restore them after a subdiagnostic is rendered.
293+ pub reserved_args : DiagArgMap ,
294+
292295 /// This is not used for highlighting or rendering any error message. Rather, it can be used
293296 /// as a sort key to sort a buffer of diagnostics. By default, it is the primary span of
294297 /// `span` if there is one. Otherwise, it is `DUMMY_SP`.
@@ -319,6 +322,7 @@ impl DiagInner {
319322 children : vec ! [ ] ,
320323 suggestions : Suggestions :: Enabled ( vec ! [ ] ) ,
321324 args : Default :: default ( ) ,
325+ reserved_args : Default :: default ( ) ,
322326 sort_span : DUMMY_SP ,
323327 is_lint : None ,
324328 long_ty_path : None ,
@@ -390,7 +394,28 @@ impl DiagInner {
390394 }
391395
392396 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 ( ) ;
394419 }
395420
396421 /// Fields used for Hash, and PartialEq trait.
@@ -1423,6 +1448,12 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
14231448 self . downgrade_to_delayed_bug ( ) ;
14241449 self . emit ( )
14251450 }
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+ }
14261457}
14271458
14281459/// Destructor bomb: every `Diag` must be consumed (emitted, cancelled, etc.)
0 commit comments