@@ -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,27 @@ 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 = std:: mem:: take ( & mut self . reserved_args ) ;
394418 }
395419
396420 /// Fields used for Hash, and PartialEq trait.
@@ -1423,6 +1447,12 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
14231447 self . downgrade_to_delayed_bug ( ) ;
14241448 self . emit ( )
14251449 }
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+ }
14261456}
14271457
14281458/// Destructor bomb: every `Diag` must be consumed (emitted, cancelled, etc.)
0 commit comments