@@ -5,10 +5,10 @@ use crate::diagnostics::error::{
5
5
SessionDiagnosticDeriveError ,
6
6
} ;
7
7
use 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 ,
10
10
} ;
11
- use proc_macro2:: TokenStream ;
11
+ use proc_macro2:: { Ident , TokenStream } ;
12
12
use quote:: { format_ident, quote} ;
13
13
use std:: collections:: HashMap ;
14
14
use std:: str:: FromStr ;
@@ -388,7 +388,8 @@ impl SessionDiagnosticDeriveBuilder {
388
388
) -> Result < TokenStream , SessionDiagnosticDeriveError > {
389
389
let diag = & self . diag ;
390
390
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 ( ) ;
392
393
let name = name. as_str ( ) ;
393
394
394
395
let meta = attr. parse_meta ( ) ?;
@@ -405,9 +406,18 @@ impl SessionDiagnosticDeriveBuilder {
405
406
#diag. set_span( #binding) ;
406
407
} )
407
408
}
408
- "label" | "note" | "help" => {
409
+ "label" => {
409
410
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
+ }
411
421
}
412
422
"subdiagnostic" => Ok ( quote ! { #diag. subdiagnostic( #binding) ; } ) ,
413
423
_ => throw_invalid_attr ! ( attr, & meta, |diag| {
@@ -416,9 +426,18 @@ impl SessionDiagnosticDeriveBuilder {
416
426
} ) ,
417
427
} ,
418
428
Meta :: NameValue ( MetaNameValue { lit : syn:: Lit :: Str ( ref s) , .. } ) => match name {
419
- "label" | "note" | "help" => {
429
+ "label" => {
420
430
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
+ }
422
441
}
423
442
_ => throw_invalid_attr ! ( attr, & meta, |diag| {
424
443
diag. help( "only `label`, `note` and `help` are valid field attributes" )
@@ -510,12 +529,12 @@ impl SessionDiagnosticDeriveBuilder {
510
529
}
511
530
}
512
531
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 (
516
535
& self ,
517
536
field_binding : TokenStream ,
518
- kind : & str ,
537
+ kind : & Ident ,
519
538
fluent_attr_identifier : & str ,
520
539
) -> TokenStream {
521
540
let diag = & self . diag ;
@@ -531,6 +550,16 @@ impl SessionDiagnosticDeriveBuilder {
531
550
}
532
551
}
533
552
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
+
534
563
fn span_and_applicability_of_ty (
535
564
& self ,
536
565
info : FieldInfo < ' _ > ,
0 commit comments