1+ use std:: borrow:: Cow ;
12use std:: cell:: RefCell ;
23use std:: collections:: BTreeMap ;
34use std:: ops:: { Deref , DerefMut } ;
@@ -766,6 +767,7 @@ impl<'sess> AttributeParser<'sess, Early> {
766767 sess,
767768 attrs,
768769 Some ( sym) ,
770+ Target :: Crate , // Does not matter, we're not going to emit errors anyways
769771 target_span,
770772 target_node_id,
771773 features,
@@ -779,6 +781,7 @@ impl<'sess> AttributeParser<'sess, Early> {
779781 sess : & ' sess Session ,
780782 attrs : & [ ast:: Attribute ] ,
781783 parse_only : Option < Symbol > ,
784+ target : Target ,
782785 target_span : Span ,
783786 target_node_id : NodeId ,
784787 features : Option < & ' sess Features > ,
@@ -790,11 +793,12 @@ impl<'sess> AttributeParser<'sess, Early> {
790793 attrs,
791794 target_span,
792795 target_node_id,
793- Target :: Crate , // Does not matter, we're not going to emit errors anyways
796+ target ,
794797 OmitDoc :: Skip ,
795798 std:: convert:: identity,
796799 |_lint| {
797- panic ! ( "can't emit lints here for now (nothing uses this atm)" ) ;
800+ // FIXME: Can't emit lints here for now
801+ // This branch can be hit when an attribute produces a warning during early parsing (such as attributes on macro calls)
798802 } ,
799803 )
800804 }
@@ -806,9 +810,9 @@ impl<'sess> AttributeParser<'sess, Early> {
806810 target_node_id : NodeId ,
807811 features : Option < & ' sess Features > ,
808812 emit_errors : ShouldEmit ,
809- parse_fn : fn ( cx : & mut AcceptContext < ' _ , ' _ , Early > , item : & ArgParser < ' _ > ) -> T ,
813+ parse_fn : fn ( cx : & mut AcceptContext < ' _ , ' _ , Early > , item : & ArgParser < ' _ > ) -> Option < T > ,
810814 template : & AttributeTemplate ,
811- ) -> T {
815+ ) -> Option < T > {
812816 let mut parser = Self {
813817 features,
814818 tools : Vec :: new ( ) ,
@@ -819,7 +823,9 @@ impl<'sess> AttributeParser<'sess, Early> {
819823 let ast:: AttrKind :: Normal ( normal_attr) = & attr. kind else {
820824 panic ! ( "parse_single called on a doc attr" )
821825 } ;
822- let meta_parser = MetaItemParser :: from_attr ( normal_attr, parser. dcx ( ) ) ;
826+ let parts =
827+ normal_attr. item . path . segments . iter ( ) . map ( |seg| seg. ident . name ) . collect :: < Vec < _ > > ( ) ;
828+ let meta_parser = MetaItemParser :: from_attr ( normal_attr, & parts, & sess. psess , emit_errors) ?;
823829 let path = meta_parser. path ( ) ;
824830 let args = meta_parser. args ( ) ;
825831 let mut cx: AcceptContext < ' _ , ' sess , Early > = AcceptContext {
@@ -926,14 +932,23 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
926932 // }))
927933 // }
928934 ast:: AttrKind :: Normal ( n) => {
929- attr_paths. push ( PathParser :: Ast ( & n. item . path ) ) ;
935+ attr_paths. push ( PathParser ( Cow :: Borrowed ( & n. item . path ) ) ) ;
930936
931- let parser = MetaItemParser :: from_attr ( n, self . dcx ( ) ) ;
932- let path = parser. path ( ) ;
933- let args = parser. args ( ) ;
934- let parts = path. segments ( ) . map ( |i| i. name ) . collect :: < Vec < _ > > ( ) ;
937+ let parts =
938+ n. item . path . segments . iter ( ) . map ( |seg| seg. ident . name ) . collect :: < Vec < _ > > ( ) ;
935939
936940 if let Some ( accepts) = S :: parsers ( ) . accepters . get ( parts. as_slice ( ) ) {
941+ let Some ( parser) = MetaItemParser :: from_attr (
942+ n,
943+ & parts,
944+ & self . sess . psess ,
945+ self . stage . should_emit ( ) ,
946+ ) else {
947+ continue ;
948+ } ;
949+ let path = parser. path ( ) ;
950+ let args = parser. args ( ) ;
951+
937952 for accept in accepts {
938953 let mut cx: AcceptContext < ' _ , ' sess , S > = AcceptContext {
939954 shared : SharedContext {
0 commit comments