4242
4343use rustc_ast:: node_id:: NodeMap ;
4444use rustc_ast:: { self as ast, * } ;
45+ use rustc_attr_parsing:: { AttributeParseContext , OmitDoc } ;
4546use rustc_data_structures:: captures:: Captures ;
4647use rustc_data_structures:: fingerprint:: Fingerprint ;
4748use rustc_data_structures:: sorted_map:: SortedMap ;
@@ -133,10 +134,13 @@ struct LoweringContext<'a, 'hir> {
133134 allow_async_iterator : Lrc < [ Symbol ] > ,
134135 allow_for_await : Lrc < [ Symbol ] > ,
135136 allow_async_fn_traits : Lrc < [ Symbol ] > ,
137+
138+ attribute_parse_context : AttributeParseContext < ' hir > ,
136139}
137140
138141impl < ' a , ' hir > LoweringContext < ' a , ' hir > {
139142 fn new ( tcx : TyCtxt < ' hir > , resolver : & ' a mut ResolverAstLowering ) -> Self {
143+ let registered_tools = tcx. registered_tools ( ( ) ) . iter ( ) . map ( |x| x. name ) . collect ( ) ;
140144 Self {
141145 // Pseudo-globals.
142146 tcx,
@@ -176,6 +180,12 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
176180 // FIXME(gen_blocks): how does `closure_track_caller`/`async_fn_track_caller`
177181 // interact with `gen`/`async gen` blocks
178182 allow_async_iterator : [ sym:: gen_future, sym:: async_iterator] . into ( ) ,
183+
184+ attribute_parse_context : AttributeParseContext :: new (
185+ tcx. sess ,
186+ tcx. features ( ) ,
187+ registered_tools,
188+ ) ,
179189 }
180190 }
181191
@@ -211,7 +221,6 @@ impl ResolverAstLowering {
211221 None
212222 }
213223
214- /// Obtains resolution for a `NodeId` with a single resolution.
215224 fn get_partial_res ( & self , id : NodeId ) -> Option < PartialRes > {
216225 self . partial_res_map . get ( & id) . copied ( )
217226 }
@@ -839,45 +848,27 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
839848 ret
840849 }
841850
842- fn lower_attrs ( & mut self , id : HirId , attrs : & [ Attribute ] ) -> & ' hir [ hir:: Attribute ] {
851+ fn lower_attrs (
852+ & mut self ,
853+ id : HirId ,
854+ attrs : & [ Attribute ] ,
855+ target_span : Span ,
856+ ) -> & ' hir [ hir:: Attribute ] {
843857 if attrs. is_empty ( ) {
844858 & [ ]
845859 } else {
860+ let lowered_attrs = self . lower_attrs_vec ( attrs, target_span) ;
861+
846862 debug_assert_eq ! ( id. owner, self . current_hir_id_owner) ;
847- let ret = self . arena . alloc_from_iter ( attrs . iter ( ) . map ( |a| self . lower_attr ( a ) ) ) ;
863+ let ret = self . arena . alloc_from_iter ( lowered_attrs ) ;
848864 debug_assert ! ( !ret. is_empty( ) ) ;
849865 self . attrs . insert ( id. local_id , ret) ;
850866 ret
851867 }
852868 }
853869
854- fn lower_attr ( & self , attr : & Attribute ) -> hir:: Attribute {
855- // Note that we explicitly do not walk the path. Since we don't really
856- // lower attributes (we use the AST version) there is nowhere to keep
857- // the `HirId`s. We don't actually need HIR version of attributes anyway.
858- // Tokens are also not needed after macro expansion and parsing.
859- let kind = match attr. kind {
860- AttrKind :: Normal ( ref normal) => hir:: AttrKind :: Normal ( Box :: new ( hir:: AttrItem {
861- unsafety : self . lower_safety ( normal. item . unsafety , hir:: Safety :: Safe ) ,
862- path : hir:: AttrPath {
863- segments : normal
864- . item
865- . path
866- . segments
867- . iter ( )
868- . map ( |i| i. ident )
869- . collect :: < Vec < _ > > ( )
870- . into_boxed_slice ( ) ,
871- span : normal. item . path . span ,
872- } ,
873- args : self . lower_attr_args ( & normal. item . args ) ,
874- } ) ) ,
875- AttrKind :: DocComment ( comment_kind, data) => {
876- hir:: AttrKind :: DocComment ( comment_kind, data)
877- }
878- } ;
879-
880- hir:: Attribute { kind, id : attr. id , style : attr. style , span : self . lower_span ( attr. span ) }
870+ fn lower_attrs_vec ( & self , attrs : & [ Attribute ] , target_span : Span ) -> Vec < hir:: Attribute > {
871+ self . attribute_parse_context . parse_attribute_list ( attrs, target_span, OmitDoc :: Lower )
881872 }
882873
883874 fn alias_attrs ( & mut self , id : HirId , target_id : HirId ) {
@@ -889,34 +880,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
889880 }
890881 }
891882
892- fn lower_attr_args ( & self , args : & AttrArgs ) -> hir:: AttrArgs {
893- match args {
894- AttrArgs :: Empty => hir:: AttrArgs :: Empty ,
895- AttrArgs :: Delimited ( args) => hir:: AttrArgs :: Delimited ( self . lower_delim_args ( args) ) ,
896- // This is an inert key-value attribute - it will never be visible to macros
897- // after it gets lowered to HIR. Therefore, we can extract literals to handle
898- // nonterminals in `#[doc]` (e.g. `#[doc = $e]`).
899- & AttrArgs :: Eq { eq_span, ref expr } => {
900- // In valid code the value always ends up as a single literal. Otherwise, a dummy
901- // literal suffices because the error is handled elsewhere.
902- let lit = if let ExprKind :: Lit ( token_lit) = expr. kind
903- && let Ok ( lit) = MetaItemLit :: from_token_lit ( token_lit, expr. span )
904- {
905- lit
906- } else {
907- let guar = self . dcx ( ) . has_errors ( ) . unwrap ( ) ;
908- MetaItemLit {
909- symbol : kw:: Empty ,
910- suffix : None ,
911- kind : LitKind :: Err ( guar) ,
912- span : DUMMY_SP ,
913- }
914- } ;
915- hir:: AttrArgs :: Eq { eq_span, expr : lit }
916- }
917- }
918- }
919-
920883 fn lower_delim_args ( & self , args : & DelimArgs ) -> DelimArgs {
921884 DelimArgs { dspan : args. dspan , delim : args. delim , tokens : args. tokens . flattened ( ) }
922885 }
@@ -1807,7 +1770,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
18071770 let ( name, kind) = self . lower_generic_param_kind ( param, source) ;
18081771
18091772 let hir_id = self . lower_node_id ( param. id ) ;
1810- self . lower_attrs ( hir_id, & param. attrs ) ;
1773+ self . lower_attrs ( hir_id, & param. attrs , param . span ( ) ) ;
18111774 hir:: GenericParam {
18121775 hir_id,
18131776 def_id : self . local_def_id ( param. id ) ,
0 commit comments