@@ -5,10 +5,10 @@ use crate::diagnostics::error::{
55 SessionDiagnosticDeriveError ,
66} ;
77use crate :: diagnostics:: utils:: {
8- report_error_if_not_applied_to_span, type_matches_path , Applicability , FieldInfo , FieldInnerTy ,
9- HasFieldMap , SetOnce ,
8+ report_error_if_not_applied_to_span, report_type_error , type_is_unit , type_matches_path ,
9+ Applicability , FieldInfo , FieldInnerTy , HasFieldMap , SetOnce ,
1010} ;
11- use proc_macro2:: TokenStream ;
11+ use proc_macro2:: { Ident , TokenStream } ;
1212use quote:: { format_ident, quote} ;
1313use std:: collections:: HashMap ;
1414use std:: str:: FromStr ;
@@ -388,7 +388,8 @@ impl SessionDiagnosticDeriveBuilder {
388388 ) -> Result < TokenStream , SessionDiagnosticDeriveError > {
389389 let diag = & self . diag ;
390390
391- let name = attr. path . segments . last ( ) . unwrap ( ) . ident . to_string ( ) ;
391+ let ident = & attr. path . segments . last ( ) . unwrap ( ) . ident ;
392+ let name = ident. to_string ( ) ;
392393 let name = name. as_str ( ) ;
393394
394395 let meta = attr. parse_meta ( ) ?;
@@ -405,9 +406,18 @@ impl SessionDiagnosticDeriveBuilder {
405406 #diag. set_span( #binding) ;
406407 } )
407408 }
408- "label" | "note" | "help" => {
409+ "label" => {
409410 report_error_if_not_applied_to_span ( attr, & info) ?;
410- Ok ( self . add_subdiagnostic ( binding, name, name) )
411+ Ok ( self . add_spanned_subdiagnostic ( binding, ident, name) )
412+ }
413+ "note" | "help" => {
414+ if type_matches_path ( & info. ty , & [ "rustc_span" , "Span" ] ) {
415+ Ok ( self . add_spanned_subdiagnostic ( binding, ident, name) )
416+ } else if type_is_unit ( & info. ty ) {
417+ Ok ( self . add_subdiagnostic ( ident, name) )
418+ } else {
419+ report_type_error ( attr, "`Span` or `()`" ) ?;
420+ }
411421 }
412422 "subdiagnostic" => Ok ( quote ! { #diag. subdiagnostic( #binding) ; } ) ,
413423 _ => throw_invalid_attr ! ( attr, & meta, |diag| {
@@ -416,9 +426,18 @@ impl SessionDiagnosticDeriveBuilder {
416426 } ) ,
417427 } ,
418428 Meta :: NameValue ( MetaNameValue { lit : syn:: Lit :: Str ( ref s) , .. } ) => match name {
419- "label" | "note" | "help" => {
429+ "label" => {
420430 report_error_if_not_applied_to_span ( attr, & info) ?;
421- Ok ( self . add_subdiagnostic ( binding, name, & s. value ( ) ) )
431+ Ok ( self . add_spanned_subdiagnostic ( binding, ident, & s. value ( ) ) )
432+ }
433+ "note" | "help" => {
434+ if type_matches_path ( & info. ty , & [ "rustc_span" , "Span" ] ) {
435+ Ok ( self . add_spanned_subdiagnostic ( binding, ident, & s. value ( ) ) )
436+ } else if type_is_unit ( & info. ty ) {
437+ Ok ( self . add_subdiagnostic ( ident, & s. value ( ) ) )
438+ } else {
439+ report_type_error ( attr, "`Span` or `()`" ) ?;
440+ }
422441 }
423442 _ => throw_invalid_attr ! ( attr, & meta, |diag| {
424443 diag. help( "only `label`, `note` and `help` are valid field attributes" )
@@ -510,12 +529,12 @@ impl SessionDiagnosticDeriveBuilder {
510529 }
511530 }
512531
513- /// Adds a subdiagnostic by generating a `diag.span_$kind` call with the current slug and
514- /// `fluent_attr_identifier`.
515- fn add_subdiagnostic (
532+ /// Adds a spanned subdiagnostic by generating a `diag.span_$kind` call with the current slug
533+ /// and `fluent_attr_identifier`.
534+ fn add_spanned_subdiagnostic (
516535 & self ,
517536 field_binding : TokenStream ,
518- kind : & str ,
537+ kind : & Ident ,
519538 fluent_attr_identifier : & str ,
520539 ) -> TokenStream {
521540 let diag = & self . diag ;
@@ -531,6 +550,16 @@ impl SessionDiagnosticDeriveBuilder {
531550 }
532551 }
533552
553+ /// Adds a subdiagnostic by generating a `diag.span_$kind` call with the current slug
554+ /// and `fluent_attr_identifier`.
555+ fn add_subdiagnostic ( & self , kind : & Ident , fluent_attr_identifier : & str ) -> TokenStream {
556+ let diag = & self . diag ;
557+ let slug = self . slug . as_ref ( ) . map ( |( slug, _) | slug. as_str ( ) ) . unwrap_or ( "missing-slug" ) ;
558+ quote ! {
559+ #diag. #kind( rustc_errors:: DiagnosticMessage :: fluent_attr( #slug, #fluent_attr_identifier) ) ;
560+ }
561+ }
562+
534563 fn span_and_applicability_of_ty (
535564 & self ,
536565 info : FieldInfo < ' _ > ,
0 commit comments