11#![ deny( unused_must_use) ]
22
3- use crate :: diagnostics:: error:: { span_err, throw_span_err, SessionDiagnosticDeriveError } ;
3+ use crate :: diagnostics:: error:: {
4+ invalid_nested_attr, span_err, throw_invalid_attr, throw_invalid_nested_attr, throw_span_err,
5+ SessionDiagnosticDeriveError ,
6+ } ;
47use crate :: diagnostics:: utils:: {
58 option_inner_ty, report_error_if_not_applied_to_span, type_matches_path, FieldInfo , HasFieldMap ,
69} ;
@@ -292,39 +295,24 @@ impl SessionDiagnosticDeriveBuilder {
292295 }
293296
294297 let nested = match meta {
295- Meta :: List ( MetaList { nested, .. } ) => nested,
296- Meta :: Path ( ..) => throw_span_err ! (
297- span,
298- & format!( "`#[{}]` is not a valid `SessionDiagnostic` struct attribute" , name)
299- ) ,
300- Meta :: NameValue ( ..) => throw_span_err ! (
301- span,
302- & format!( "`#[{} = ...]` is not a valid `SessionDiagnostic` struct attribute" , name)
303- ) ,
298+ Meta :: List ( MetaList { ref nested, .. } ) => nested,
299+ _ => throw_invalid_attr ! ( attr, & meta) ,
304300 } ;
305301
306302 let kind = match name {
307303 "error" => SessionDiagnosticKind :: Error ,
308304 "warning" => SessionDiagnosticKind :: Warn ,
309- other => throw_span_err ! (
310- span,
311- & format!( "`#[{}(...)]` is not a valid `SessionDiagnostic` struct attribute" , other)
312- ) ,
305+ _ => throw_invalid_attr ! ( attr, & meta, |diag| {
306+ diag. help( "only `error` and `warning` are valid attributes" )
307+ } ) ,
313308 } ;
314309 self . set_kind_once ( kind, span) ?;
315310
316311 let mut tokens = Vec :: new ( ) ;
317- for attr in nested {
318- let span = attr. span ( ) . unwrap ( ) ;
319- let meta = match attr {
312+ for nested_attr in nested {
313+ let meta = match nested_attr {
320314 syn:: NestedMeta :: Meta ( meta) => meta,
321- syn:: NestedMeta :: Lit ( _) => throw_span_err ! (
322- span,
323- & format!(
324- "`#[{}(\" ...\" )]` is not a valid `SessionDiagnostic` struct attribute" ,
325- name
326- )
327- ) ,
315+ _ => throw_invalid_nested_attr ! ( attr, & nested_attr) ,
328316 } ;
329317
330318 let path = meta. path ( ) ;
@@ -340,49 +328,12 @@ impl SessionDiagnosticDeriveBuilder {
340328 "code" => {
341329 tokens. push ( self . set_code_once ( s. value ( ) , s. span ( ) . unwrap ( ) ) ) ;
342330 }
343- other => {
344- let diag = span_err (
345- span,
346- & format ! (
347- "`#[{}({} = ...)]` is not a valid `SessionDiagnostic` struct attribute" ,
348- name, other
349- ) ,
350- ) ;
351- diag. emit ( ) ;
352- }
331+ _ => invalid_nested_attr ( attr, & nested_attr)
332+ . help ( "only `slug` and `code` are valid nested attributes" )
333+ . emit ( ) ,
353334 }
354335 }
355- Meta :: NameValue ( ..) => {
356- span_err (
357- span,
358- & format ! (
359- "`#[{}({} = ...)]` is not a valid `SessionDiagnostic` struct attribute" ,
360- name, nested_name
361- ) ,
362- )
363- . help ( "value must be a string" )
364- . emit ( ) ;
365- }
366- Meta :: Path ( ..) => {
367- span_err (
368- span,
369- & format ! (
370- "`#[{}({})]` is not a valid `SessionDiagnostic` struct attribute" ,
371- name, nested_name
372- ) ,
373- )
374- . emit ( ) ;
375- }
376- Meta :: List ( ..) => {
377- span_err (
378- span,
379- & format ! (
380- "`#[{}({}(...))]` is not a valid `SessionDiagnostic` struct attribute" ,
381- name, nested_name
382- ) ,
383- )
384- . emit ( ) ;
385- }
336+ _ => invalid_nested_attr ( attr, & nested_attr) . emit ( ) ,
386337 }
387338 }
388339
@@ -478,7 +429,6 @@ impl SessionDiagnosticDeriveBuilder {
478429 info : FieldInfo < ' _ > ,
479430 ) -> Result < TokenStream , SessionDiagnosticDeriveError > {
480431 let diag = & self . diag ;
481- let span = attr. span ( ) . unwrap ( ) ;
482432 let field_binding = & info. binding . binding ;
483433
484434 let name = attr. path . segments . last ( ) . unwrap ( ) . ident . to_string ( ) ;
@@ -502,66 +452,46 @@ impl SessionDiagnosticDeriveBuilder {
502452 report_error_if_not_applied_to_span ( attr, & info) ?;
503453 Ok ( self . add_subdiagnostic ( field_binding, name, name) )
504454 }
505- other => throw_span_err ! (
506- span ,
507- & format! ( "`#[{}]` is not a valid `SessionDiagnostic` field attribute" , other )
508- ) ,
455+ _ => throw_invalid_attr ! ( attr , & meta , |diag| {
456+ diag
457+ . help ( "only `skip_arg`, `primary_span`, `label`, `note` and `help` are valid field attributes" )
458+ } ) ,
509459 } ,
510- Meta :: NameValue ( MetaNameValue { lit : syn:: Lit :: Str ( s) , .. } ) => match name {
460+ Meta :: NameValue ( MetaNameValue { lit : syn:: Lit :: Str ( ref s) , .. } ) => match name {
511461 "label" | "note" | "help" => {
512462 report_error_if_not_applied_to_span ( attr, & info) ?;
513463 Ok ( self . add_subdiagnostic ( field_binding, name, & s. value ( ) ) )
514464 }
515- other => throw_span_err ! (
516- span,
517- & format!(
518- "`#[{} = ...]` is not a valid `SessionDiagnostic` field attribute" ,
519- other
520- )
521- ) ,
465+ _ => throw_invalid_attr ! ( attr, & meta, |diag| {
466+ diag. help( "only `label`, `note` and `help` are valid field attributes" )
467+ } ) ,
522468 } ,
523- Meta :: NameValue ( _) => throw_span_err ! (
524- span,
525- & format!( "`#[{} = ...]` is not a valid `SessionDiagnostic` field attribute" , name) ,
526- |diag| diag. help( "value must be a string" )
527- ) ,
528- Meta :: List ( MetaList { path, nested, .. } ) => {
469+ Meta :: List ( MetaList { ref path, ref nested, .. } ) => {
529470 let name = path. segments . last ( ) . unwrap ( ) . ident . to_string ( ) ;
530471 let name = name. as_ref ( ) ;
531472
532473 match name {
533474 "suggestion" | "suggestion_short" | "suggestion_hidden"
534475 | "suggestion_verbose" => ( ) ,
535- other => throw_span_err ! (
536- span,
537- & format!(
538- "`#[{}(...)]` is not a valid `SessionDiagnostic` field attribute" ,
539- other
540- )
541- ) ,
476+ _ => throw_invalid_attr ! ( attr, & meta, |diag| {
477+ diag
478+ . help( "only `suggestion{,_short,_hidden,_verbose}` are valid field attributes" )
479+ } ) ,
542480 } ;
543481
544482 let ( span_, applicability) = self . span_and_applicability_of_ty ( info) ?;
545483
546484 let mut msg = None ;
547485 let mut code = None ;
548486
549- for attr in nested {
550- let meta = match attr {
551- syn:: NestedMeta :: Meta ( meta) => meta,
552- syn:: NestedMeta :: Lit ( _) => throw_span_err ! (
553- span,
554- & format!(
555- "`#[{}(\" ...\" )]` is not a valid `SessionDiagnostic` field attribute" ,
556- name
557- )
558- ) ,
487+ for nested_attr in nested {
488+ let meta = match nested_attr {
489+ syn:: NestedMeta :: Meta ( ref meta) => meta,
490+ syn:: NestedMeta :: Lit ( _) => throw_invalid_nested_attr ! ( attr, & nested_attr) ,
559491 } ;
560492
561- let span = meta. span ( ) . unwrap ( ) ;
562493 let nested_name = meta. path ( ) . segments . last ( ) . unwrap ( ) . ident . to_string ( ) ;
563494 let nested_name = nested_name. as_str ( ) ;
564-
565495 match meta {
566496 Meta :: NameValue ( MetaNameValue { lit : syn:: Lit :: Str ( s) , .. } ) => {
567497 match nested_name {
@@ -572,37 +502,14 @@ impl SessionDiagnosticDeriveBuilder {
572502 let formatted_str = self . build_format ( & s. value ( ) , s. span ( ) ) ;
573503 code = Some ( formatted_str) ;
574504 }
575- other => throw_span_err ! (
576- span,
577- & format!(
578- "`#[{}({} = ...)]` is not a valid `SessionDiagnostic` field attribute" ,
579- name, other
505+ _ => throw_invalid_nested_attr ! ( attr, & nested_attr, |diag| {
506+ diag. help(
507+ "only `message` and `code` are valid field attributes" ,
580508 )
581- ) ,
509+ } ) ,
582510 }
583511 }
584- Meta :: NameValue ( ..) => throw_span_err ! (
585- span,
586- & format!(
587- "`#[{}({} = ...)]` is not a valid `SessionDiagnostic` struct attribute" ,
588- name, nested_name
589- ) ,
590- |diag| diag. help( "value must be a string" )
591- ) ,
592- Meta :: Path ( ..) => throw_span_err ! (
593- span,
594- & format!(
595- "`#[{}({})]` is not a valid `SessionDiagnostic` struct attribute" ,
596- name, nested_name
597- )
598- ) ,
599- Meta :: List ( ..) => throw_span_err ! (
600- span,
601- & format!(
602- "`#[{}({}(...))]` is not a valid `SessionDiagnostic` struct attribute" ,
603- name, nested_name
604- )
605- ) ,
512+ _ => throw_invalid_nested_attr ! ( attr, & nested_attr) ,
606513 }
607514 }
608515
@@ -619,6 +526,7 @@ impl SessionDiagnosticDeriveBuilder {
619526
620527 Ok ( quote ! { #diag. #method( #span_, #msg, #code, #applicability) ; } )
621528 }
529+ _ => throw_invalid_attr ! ( attr, & meta) ,
622530 }
623531 }
624532
0 commit comments