@@ -2,7 +2,7 @@ use std::convert::identity;
22
33use rustc_ast as ast;
44use rustc_ast:: token:: DocFragmentKind ;
5- use rustc_ast:: { AttrStyle , NodeId , Safety } ;
5+ use rustc_ast:: { AttrItemKind , AttrStyle , NodeId , Safety } ;
66use rustc_errors:: DiagCtxtHandle ;
77use rustc_feature:: { AttributeTemplate , Features } ;
88use rustc_hir:: attrs:: AttributeKind ;
@@ -13,6 +13,7 @@ use rustc_session::lint::BuiltinLintDiag;
1313use rustc_span:: { DUMMY_SP , Span , Symbol , sym} ;
1414
1515use crate :: context:: { AcceptContext , FinalizeContext , SharedContext , Stage } ;
16+ use crate :: early_parsed:: { EARLY_PARSED_ATTRIBUTES , EarlyParsedState } ;
1617use crate :: parser:: { ArgParser , PathParser , RefPathParser } ;
1718use crate :: session_diagnostics:: ParsedDescription ;
1819use crate :: { Early , Late , OmitDoc , ShouldEmit } ;
@@ -146,8 +147,12 @@ impl<'sess> AttributeParser<'sess, Early> {
146147 normal_attr. item . path . segments . iter ( ) . map ( |seg| seg. ident . name ) . collect :: < Vec < _ > > ( ) ;
147148
148149 let path = AttrPath :: from_ast ( & normal_attr. item . path , identity) ;
149- let args =
150- ArgParser :: from_attr_args ( & normal_attr. item . args , & parts, & sess. psess , emit_errors) ?;
150+ let args = ArgParser :: from_attr_args (
151+ & normal_attr. item . args . unparsed_ref ( ) . unwrap ( ) ,
152+ & parts,
153+ & sess. psess ,
154+ emit_errors,
155+ ) ?;
151156 Self :: parse_single_args (
152157 sess,
153158 attr. span ,
@@ -263,12 +268,12 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
263268 target_id : S :: Id ,
264269 target : Target ,
265270 omit_doc : OmitDoc ,
266-
267271 lower_span : impl Copy + Fn ( Span ) -> Span ,
268272 mut emit_lint : impl FnMut ( AttributeLint < S :: Id > ) ,
269273 ) -> Vec < Attribute > {
270274 let mut attributes = Vec :: new ( ) ;
271275 let mut attr_paths: Vec < RefPathParser < ' _ > > = Vec :: new ( ) ;
276+ let mut early_parsed_state = EarlyParsedState :: default ( ) ;
272277
273278 for attr in attrs {
274279 // If we're only looking for a single attribute, skip all the ones we don't care about.
@@ -288,6 +293,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
288293 continue ;
289294 }
290295
296+ let attr_span = lower_span ( attr. span ) ;
291297 match & attr. kind {
292298 ast:: AttrKind :: DocComment ( comment_kind, symbol) => {
293299 if omit_doc == OmitDoc :: Skip {
@@ -297,14 +303,23 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
297303 attributes. push ( Attribute :: Parsed ( AttributeKind :: DocComment {
298304 style : attr. style ,
299305 kind : DocFragmentKind :: Sugared ( * comment_kind) ,
300- span : lower_span ( attr . span ) ,
306+ span : attr_span ,
301307 comment : * symbol,
302308 } ) )
303309 }
304310 ast:: AttrKind :: Normal ( n) => {
305311 attr_paths. push ( PathParser ( & n. item . path ) ) ;
306312 let attr_path = AttrPath :: from_ast ( & n. item . path , lower_span) ;
307313
314+ let args = match & n. item . args {
315+ AttrItemKind :: Unparsed ( args) => args,
316+ AttrItemKind :: Parsed ( parsed) => {
317+ early_parsed_state
318+ . accept_early_parsed_attribute ( attr_span, lower_span, parsed) ;
319+ continue ;
320+ }
321+ } ;
322+
308323 self . check_attribute_safety (
309324 & attr_path,
310325 lower_span ( n. item . span ( ) ) ,
@@ -318,7 +333,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
318333
319334 if let Some ( accepts) = S :: parsers ( ) . accepters . get ( parts. as_slice ( ) ) {
320335 let Some ( args) = ArgParser :: from_attr_args (
321- & n . item . args ,
336+ args,
322337 & parts,
323338 & self . sess . psess ,
324339 self . stage . should_emit ( ) ,
@@ -351,7 +366,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
351366 attributes. push ( Attribute :: Parsed ( AttributeKind :: DocComment {
352367 style : attr. style ,
353368 kind : DocFragmentKind :: Raw ( nv. value_span ) ,
354- span : attr . span ,
369+ span : attr_span ,
355370 comment,
356371 } ) ) ;
357372 continue ;
@@ -365,7 +380,7 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
365380 target_id,
366381 emit_lint : & mut emit_lint,
367382 } ,
368- attr_span : lower_span ( attr . span ) ,
383+ attr_span,
369384 inner_span : lower_span ( n. item . span ( ) ) ,
370385 attr_style : attr. style ,
371386 parsed_description : ParsedDescription :: Attribute ,
@@ -396,17 +411,18 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
396411
397412 attributes. push ( Attribute :: Unparsed ( Box :: new ( AttrItem {
398413 path : attr_path. clone ( ) ,
399- args : self . lower_attr_args ( & n. item . args , lower_span) ,
414+ args : self
415+ . lower_attr_args ( n. item . args . unparsed_ref ( ) . unwrap ( ) , lower_span) ,
400416 id : HashIgnoredAttrId { attr_id : attr. id } ,
401417 style : attr. style ,
402- span : lower_span ( attr . span ) ,
418+ span : attr_span ,
403419 } ) ) ) ;
404420 }
405421 }
406422 }
407423 }
408424
409- let mut parsed_attributes = Vec :: new ( ) ;
425+ early_parsed_state . finalize_early_parsed_attributes ( & mut attributes ) ;
410426 for f in & S :: parsers ( ) . finalizers {
411427 if let Some ( attr) = f ( & mut FinalizeContext {
412428 shared : SharedContext {
@@ -417,18 +433,16 @@ impl<'sess, S: Stage> AttributeParser<'sess, S> {
417433 } ,
418434 all_attrs : & attr_paths,
419435 } ) {
420- parsed_attributes . push ( Attribute :: Parsed ( attr) ) ;
436+ attributes . push ( Attribute :: Parsed ( attr) ) ;
421437 }
422438 }
423439
424- attributes. extend ( parsed_attributes) ;
425-
426440 attributes
427441 }
428442
429443 /// Returns whether there is a parser for an attribute with this name
430444 pub fn is_parsed_attribute ( path : & [ Symbol ] ) -> bool {
431- Late :: parsers ( ) . accepters . contains_key ( path)
445+ Late :: parsers ( ) . accepters . contains_key ( path) || EARLY_PARSED_ATTRIBUTES . contains ( & path )
432446 }
433447
434448 fn lower_attr_args ( & self , args : & ast:: AttrArgs , lower_span : impl Fn ( Span ) -> Span ) -> AttrArgs {
0 commit comments