1
+ use std:: borrow:: Cow ;
1
2
use std:: cell:: RefCell ;
2
3
use std:: collections:: BTreeMap ;
3
4
use std:: ops:: { Deref , DerefMut } ;
@@ -766,6 +767,7 @@ impl<'sess> AttributeParser<'sess, Early> {
766
767
sess,
767
768
attrs,
768
769
Some ( sym) ,
770
+ Target :: Crate , // Does not matter, we're not going to emit errors anyways
769
771
target_span,
770
772
target_node_id,
771
773
features,
@@ -779,6 +781,7 @@ impl<'sess> AttributeParser<'sess, Early> {
779
781
sess : & ' sess Session ,
780
782
attrs : & [ ast:: Attribute ] ,
781
783
parse_only : Option < Symbol > ,
784
+ target : Target ,
782
785
target_span : Span ,
783
786
target_node_id : NodeId ,
784
787
features : Option < & ' sess Features > ,
@@ -790,11 +793,12 @@ impl<'sess> AttributeParser<'sess, Early> {
790
793
attrs,
791
794
target_span,
792
795
target_node_id,
793
- Target :: Crate , // Does not matter, we're not going to emit errors anyways
796
+ target ,
794
797
OmitDoc :: Skip ,
795
798
std:: convert:: identity,
796
799
|_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)
798
802
} ,
799
803
)
800
804
}
@@ -806,9 +810,9 @@ impl<'sess> AttributeParser<'sess, Early> {
806
810
target_node_id : NodeId ,
807
811
features : Option < & ' sess Features > ,
808
812
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 > ,
810
814
template : & AttributeTemplate ,
811
- ) -> T {
815
+ ) -> Option < T > {
812
816
let mut parser = Self {
813
817
features,
814
818
tools : Vec :: new ( ) ,
@@ -819,7 +823,9 @@ impl<'sess> AttributeParser<'sess, Early> {
819
823
let ast:: AttrKind :: Normal ( normal_attr) = & attr. kind else {
820
824
panic ! ( "parse_single called on a doc attr" )
821
825
} ;
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) ?;
823
829
let path = meta_parser. path ( ) ;
824
830
let args = meta_parser. args ( ) ;
825
831
let mut cx: AcceptContext < ' _ , ' sess , Early > = AcceptContext {
@@ -926,14 +932,23 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
926
932
// }))
927
933
// }
928
934
ast:: AttrKind :: Normal ( n) => {
929
- attr_paths. push ( PathParser :: Ast ( & n. item . path ) ) ;
935
+ attr_paths. push ( PathParser ( Cow :: Borrowed ( & n. item . path ) ) ) ;
930
936
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 < _ > > ( ) ;
935
939
936
940
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
+
937
952
for accept in accepts {
938
953
let mut cx: AcceptContext < ' _ , ' sess , S > = AcceptContext {
939
954
shared : SharedContext {
0 commit comments