@@ -653,6 +653,7 @@ pub(crate) mod parsing {
653
653
use crate :: parse:: { Parse , ParseStream } ;
654
654
use crate :: path:: Path ;
655
655
use crate :: { mac, token} ;
656
+ use proc_macro2:: Ident ;
656
657
use std:: fmt:: { self , Display } ;
657
658
658
659
pub ( crate ) fn parse_inner ( input : ParseStream , attrs : & mut Vec < Attribute > ) -> Result < ( ) > {
@@ -685,27 +686,38 @@ pub(crate) mod parsing {
685
686
#[ cfg_attr( docsrs, doc( cfg( feature = "parsing" ) ) ) ]
686
687
impl Parse for Meta {
687
688
fn parse ( input : ParseStream ) -> Result < Self > {
688
- let path = input . call ( Path :: parse_mod_style ) ?;
689
+ let path = parse_outermost_meta_path ( input ) ?;
689
690
parse_meta_after_path ( path, input)
690
691
}
691
692
}
692
693
693
694
#[ cfg_attr( docsrs, doc( cfg( feature = "parsing" ) ) ) ]
694
695
impl Parse for MetaList {
695
696
fn parse ( input : ParseStream ) -> Result < Self > {
696
- let path = input . call ( Path :: parse_mod_style ) ?;
697
+ let path = parse_outermost_meta_path ( input ) ?;
697
698
parse_meta_list_after_path ( path, input)
698
699
}
699
700
}
700
701
701
702
#[ cfg_attr( docsrs, doc( cfg( feature = "parsing" ) ) ) ]
702
703
impl Parse for MetaNameValue {
703
704
fn parse ( input : ParseStream ) -> Result < Self > {
704
- let path = input . call ( Path :: parse_mod_style ) ?;
705
+ let path = parse_outermost_meta_path ( input ) ?;
705
706
parse_meta_name_value_after_path ( path, input)
706
707
}
707
708
}
708
709
710
+ // Unlike meta::parse_meta_path which accepts arbitrary keywords in the path,
711
+ // only the `unsafe` keyword is accepted as an attribute's outermost path.
712
+ fn parse_outermost_meta_path ( input : ParseStream ) -> Result < Path > {
713
+ if input. peek ( Token ! [ unsafe ] ) {
714
+ let unsafe_token: Token ! [ unsafe ] = input. parse ( ) ?;
715
+ Ok ( Path :: from ( Ident :: new ( "unsafe" , unsafe_token. span ) ) )
716
+ } else {
717
+ Path :: parse_mod_style ( input)
718
+ }
719
+ }
720
+
709
721
pub ( crate ) fn parse_meta_after_path ( path : Path , input : ParseStream ) -> Result < Meta > {
710
722
if input. peek ( token:: Paren ) || input. peek ( token:: Bracket ) || input. peek ( token:: Brace ) {
711
723
parse_meta_list_after_path ( path, input) . map ( Meta :: List )
0 commit comments