@@ -229,38 +229,30 @@ impl<'a> SessionDiagnosticDerive<'a> {
229229
230230 let span = ast. span ( ) . unwrap ( ) ;
231231 let ( diag, sess) = ( & builder. diag , & builder. sess ) ;
232- let init = match ( builder. kind , builder. slug , builder . code ) {
233- ( None , _, _ ) => {
232+ let init = match ( builder. kind , builder. slug ) {
233+ ( None , _) => {
234234 span_err ( span, "diagnostic kind not specified" )
235235 . help ( "use the `#[error(...)]` attribute to create an error" )
236236 . emit ( ) ;
237237 return SessionDiagnosticDeriveError :: ErrorHandled . to_compile_error ( ) ;
238238 }
239- ( Some ( ( kind, _) ) , None , _ ) => {
239+ ( Some ( ( kind, _) ) , None ) => {
240240 span_err ( span, "`slug` not specified" )
241241 . help ( & format ! ( "use the `#[{}(slug = \" ...\" )]` attribute to set this diagnostic's slug" , kind. descr( ) ) )
242242 . emit ( ) ;
243243 return SessionDiagnosticDeriveError :: ErrorHandled . to_compile_error ( ) ;
244244 }
245- ( Some ( ( kind, _) ) , _, None ) => {
246- span_err ( span, "`code` not specified" )
247- . help ( & format ! ( "use the `#[{}(code = \" ...\" )]` attribute to set this diagnostic's error code" , kind. descr( ) ) )
248- . emit ( ) ;
249- return SessionDiagnosticDeriveError :: ErrorHandled . to_compile_error ( ) ;
250- }
251- ( Some ( ( SessionDiagnosticKind :: Error , _) ) , Some ( ( slug, _) ) , Some ( ( code, _) ) ) => {
245+ ( Some ( ( SessionDiagnosticKind :: Error , _) ) , Some ( ( slug, _) ) ) => {
252246 quote ! {
253- let mut #diag = #sess. struct_err_with_code (
247+ let mut #diag = #sess. struct_err (
254248 rustc_errors:: DiagnosticMessage :: fluent( #slug) ,
255- rustc_errors:: DiagnosticId :: Error ( #code. to_string( ) )
256249 ) ;
257250 }
258251 }
259- ( Some ( ( SessionDiagnosticKind :: Warn , _) ) , Some ( ( slug, _) ) , Some ( ( code , _ ) ) ) => {
252+ ( Some ( ( SessionDiagnosticKind :: Warn , _) ) , Some ( ( slug, _) ) ) => {
260253 quote ! {
261- let mut #diag = #sess. struct_warn_with_code (
254+ let mut #diag = #sess. struct_warn (
262255 rustc_errors:: DiagnosticMessage :: fluent( #slug) ,
263- rustc_errors:: DiagnosticId :: Error ( #code. to_string( ) )
264256 ) ;
265257 }
266258 }
@@ -363,9 +355,9 @@ struct SessionDiagnosticDeriveBuilder<'a> {
363355 /// Slug is a mandatory part of the struct attribute as corresponds to the Fluent message that
364356 /// has the actual diagnostic message.
365357 slug : Option < ( String , proc_macro:: Span ) > ,
366- /// Error codes are a mandatory part of the struct attribute. Slugs may replace error codes
367- /// in future but it is desirable to mandate error codes until such a time .
368- code : Option < ( String , proc_macro:: Span ) > ,
358+ /// Error codes are a optional part of the struct attribute - this is only set to detect
359+ /// multiple specifications .
360+ code : Option < proc_macro:: Span > ,
369361}
370362
371363impl < ' a > SessionDiagnosticDeriveBuilder < ' a > {
@@ -403,6 +395,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
403395 } ;
404396 self . set_kind_once ( kind, span) ?;
405397
398+ let mut tokens = Vec :: new ( ) ;
406399 for attr in nested {
407400 let span = attr. span ( ) . unwrap ( ) ;
408401 let meta = match attr {
@@ -427,7 +420,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
427420 self . set_slug_once ( s. value ( ) , s. span ( ) . unwrap ( ) ) ;
428421 }
429422 "code" => {
430- self . set_code_once ( s. value ( ) , s. span ( ) . unwrap ( ) ) ;
423+ tokens . push ( self . set_code_once ( s. value ( ) , s. span ( ) . unwrap ( ) ) ) ;
431424 }
432425 other => {
433426 let diag = span_err (
@@ -475,7 +468,7 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
475468 }
476469 }
477470
478- Ok ( quote ! { } )
471+ Ok ( tokens . drain ( .. ) . collect ( ) )
479472 }
480473
481474 #[ must_use]
@@ -504,17 +497,20 @@ impl<'a> SessionDiagnosticDeriveBuilder<'a> {
504497 }
505498 }
506499
507- fn set_code_once ( & mut self , code : String , span : proc_macro:: Span ) {
500+ fn set_code_once ( & mut self , code : String , span : proc_macro:: Span ) -> proc_macro2 :: TokenStream {
508501 match self . code {
509502 None => {
510- self . code = Some ( ( code , span) ) ;
503+ self . code = Some ( span) ;
511504 }
512- Some ( ( _ , prev_span) ) => {
505+ Some ( prev_span) => {
513506 span_err ( span, "`code` specified multiple times" )
514507 . span_note ( prev_span, "previously specified here" )
515508 . emit ( ) ;
516509 }
517510 }
511+
512+ let diag = & self . diag ;
513+ quote ! { #diag. code( rustc_errors:: DiagnosticId :: Error ( #code. to_string( ) ) ) ; }
518514 }
519515
520516 fn set_slug_once ( & mut self , slug : String , span : proc_macro:: Span ) {
0 commit comments