@@ -2,7 +2,7 @@ use rustc_abi::ExternAbi;
22use rustc_ast:: visit:: AssocCtxt ;
33use rustc_ast:: * ;
44use rustc_errors:: { E0570 , ErrorGuaranteed , struct_span_code_err} ;
5- use rustc_hir:: attrs:: AttributeKind ;
5+ use rustc_hir:: attrs:: { AttributeKind , EiiDecl } ;
66use rustc_hir:: def:: { DefKind , PerNS , Res } ;
77use rustc_hir:: def_id:: { CRATE_DEF_ID , LocalDefId } ;
88use rustc_hir:: {
@@ -11,6 +11,7 @@ use rustc_hir::{
1111use rustc_index:: { IndexSlice , IndexVec } ;
1212use rustc_middle:: span_bug;
1313use rustc_middle:: ty:: { ResolverAstLowering , TyCtxt } ;
14+ use rustc_span:: def_id:: DefId ;
1415use rustc_span:: edit_distance:: find_best_match_for_name;
1516use rustc_span:: { DUMMY_SP , DesugaringKind , Ident , Span , Symbol , kw, sym} ;
1617use smallvec:: { SmallVec , smallvec} ;
@@ -133,17 +134,103 @@ impl<'hir> LoweringContext<'_, 'hir> {
133134 }
134135 }
135136
137+ fn generate_extra_attrs_for_item_kind (
138+ & mut self ,
139+ id : NodeId ,
140+ i : & ItemKind ,
141+ ) -> Vec < hir:: Attribute > {
142+ match i {
143+ ItemKind :: Fn ( box Fn { eii_impls, .. } ) if eii_impls. is_empty ( ) => Vec :: new ( ) ,
144+ ItemKind :: Fn ( box Fn { eii_impls, .. } ) => {
145+ vec ! [ hir:: Attribute :: Parsed ( AttributeKind :: EiiImpls (
146+ eii_impls
147+ . iter( )
148+ . flat_map(
149+ |EiiImpl {
150+ node_id,
151+ eii_macro_path,
152+ impl_safety,
153+ span,
154+ inner_span,
155+ is_default,
156+ } | {
157+ self . lower_path_simple_eii( * node_id, eii_macro_path) . map( |did| {
158+ hir:: attrs:: EiiImpl {
159+ eii_macro: did,
160+ span: self . lower_span( * span) ,
161+ inner_span: self . lower_span( * inner_span) ,
162+ impl_marked_unsafe: self
163+ . lower_safety( * impl_safety, hir:: Safety :: Safe )
164+ . is_unsafe( ) ,
165+ is_default: * is_default,
166+ }
167+ } )
168+ } ,
169+ )
170+ . collect( ) ,
171+ ) ) ]
172+ }
173+ ItemKind :: MacroDef (
174+ _,
175+ MacroDef {
176+ eii_extern_target : Some ( EiiExternTarget { extern_item_path, impl_unsafe, span } ) ,
177+ ..
178+ } ,
179+ ) => self
180+ . lower_path_simple_eii ( id, extern_item_path)
181+ . map ( |did| {
182+ vec ! [ hir:: Attribute :: Parsed ( AttributeKind :: EiiExternTarget ( EiiDecl {
183+ eii_extern_target: did,
184+ impl_unsafe: * impl_unsafe,
185+ span: self . lower_span( * span) ,
186+ } ) ) ]
187+ } )
188+ . unwrap_or_default ( ) ,
189+ ItemKind :: ExternCrate ( ..)
190+ | ItemKind :: Use ( ..)
191+ | ItemKind :: Static ( ..)
192+ | ItemKind :: Const ( ..)
193+ | ItemKind :: Mod ( ..)
194+ | ItemKind :: ForeignMod ( ..)
195+ | ItemKind :: GlobalAsm ( ..)
196+ | ItemKind :: TyAlias ( ..)
197+ | ItemKind :: Enum ( ..)
198+ | ItemKind :: Struct ( ..)
199+ | ItemKind :: Union ( ..)
200+ | ItemKind :: Trait ( ..)
201+ | ItemKind :: TraitAlias ( ..)
202+ | ItemKind :: Impl ( ..)
203+ | ItemKind :: MacCall ( ..)
204+ | ItemKind :: MacroDef ( ..)
205+ | ItemKind :: Delegation ( ..)
206+ | ItemKind :: DelegationMac ( ..) => Vec :: new ( ) ,
207+ }
208+ }
209+
136210 fn lower_item ( & mut self , i : & Item ) -> & ' hir hir:: Item < ' hir > {
137211 let vis_span = self . lower_span ( i. vis . span ) ;
138212 let hir_id = hir:: HirId :: make_owner ( self . current_hir_id_owner . def_id ) ;
139- let attrs = self . lower_attrs ( hir_id, & i. attrs , i. span , Target :: from_ast_item ( i) ) ;
213+
214+ let extra_hir_attributes = self . generate_extra_attrs_for_item_kind ( i. id , & i. kind ) ;
215+ let attrs = self . lower_attrs_with_extra (
216+ hir_id,
217+ & i. attrs ,
218+ i. span ,
219+ Target :: from_ast_item ( i) ,
220+ & extra_hir_attributes,
221+ ) ;
222+
140223 let kind = self . lower_item_kind ( i. span , i. id , hir_id, attrs, vis_span, & i. kind ) ;
141224 let item = hir:: Item {
142225 owner_id : hir_id. expect_owner ( ) ,
143226 kind,
144227 vis_span,
145228 span : self . lower_span ( i. span ) ,
146229 has_delayed_lints : !self . delayed_lints . is_empty ( ) ,
230+ eii : find_attr ! (
231+ attrs,
232+ AttributeKind :: EiiImpls ( ..) | AttributeKind :: EiiExternTarget ( ..)
233+ ) ,
147234 } ;
148235 self . arena . alloc ( item)
149236 }
@@ -432,7 +519,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
432519 ) ;
433520 hir:: ItemKind :: TraitAlias ( constness, ident, generics, bounds)
434521 }
435- ItemKind :: MacroDef ( ident, MacroDef { body, macro_rules } ) => {
522+ ItemKind :: MacroDef ( ident, MacroDef { body, macro_rules, eii_extern_target : _ } ) => {
436523 let ident = self . lower_ident ( * ident) ;
437524 let body = Box :: new ( self . lower_delim_args ( body) ) ;
438525 let def_id = self . local_def_id ( id) ;
@@ -443,7 +530,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
443530 def_kind. descr( def_id. to_def_id( ) )
444531 ) ;
445532 } ;
446- let macro_def = self . arena . alloc ( ast:: MacroDef { body, macro_rules : * macro_rules } ) ;
533+ let macro_def = self . arena . alloc ( ast:: MacroDef {
534+ body,
535+ macro_rules : * macro_rules,
536+ eii_extern_target : None ,
537+ } ) ;
447538 hir:: ItemKind :: Macro ( ident, macro_def, macro_kinds)
448539 }
449540 ItemKind :: Delegation ( box delegation) => {
@@ -462,6 +553,16 @@ impl<'hir> LoweringContext<'_, 'hir> {
462553 }
463554 }
464555
556+ fn lower_path_simple_eii ( & mut self , id : NodeId , path : & Path ) -> Option < DefId > {
557+ let res = self . resolver . get_partial_res ( id) ?;
558+ let Some ( did) = res. expect_full_res ( ) . opt_def_id ( ) else {
559+ self . dcx ( ) . span_delayed_bug ( path. span , "should have errored in resolve" ) ;
560+ return None ;
561+ } ;
562+
563+ Some ( did)
564+ }
565+
465566 fn lower_const_item (
466567 & mut self ,
467568 ty : & Ty ,
@@ -581,6 +682,10 @@ impl<'hir> LoweringContext<'_, 'hir> {
581682 vis_span,
582683 span : this. lower_span ( use_tree. span ) ,
583684 has_delayed_lints : !this. delayed_lints . is_empty ( ) ,
685+ eii : find_attr ! (
686+ attrs,
687+ AttributeKind :: EiiImpls ( ..) | AttributeKind :: EiiExternTarget ( ..)
688+ ) ,
584689 } ;
585690 hir:: OwnerNode :: Item ( this. arena . alloc ( item) )
586691 } ) ;
0 commit comments