@@ -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 , EiiDecl } ;
5+ use rustc_hir:: attrs:: { AttributeKind , EiiDecl , EiiImplResolution } ;
66use rustc_hir:: def:: { DefKind , PerNS , Res } ;
77use rustc_hir:: def_id:: { CRATE_DEF_ID , LocalDefId } ;
88use rustc_hir:: {
@@ -134,6 +134,56 @@ impl<'hir> LoweringContext<'_, 'hir> {
134134 }
135135 }
136136
137+ fn lower_eii_extern_target (
138+ & mut self ,
139+ id : NodeId ,
140+ eii_name : Ident ,
141+ EiiExternTarget { extern_item_path, impl_unsafe } : & EiiExternTarget ,
142+ ) -> Option < EiiDecl > {
143+ self . lower_path_simple_eii ( id, extern_item_path) . map ( |did| EiiDecl {
144+ eii_extern_target : did,
145+ impl_unsafe : * impl_unsafe,
146+ name : eii_name,
147+ } )
148+ }
149+
150+ fn lower_eii_impl (
151+ & mut self ,
152+ EiiImpl {
153+ node_id,
154+ eii_macro_path,
155+ impl_safety,
156+ span,
157+ inner_span,
158+ is_default,
159+ known_eii_macro_resolution,
160+ } : & EiiImpl ,
161+ ) -> hir:: attrs:: EiiImpl {
162+ let resolution = if let Some ( target) = known_eii_macro_resolution
163+ && let Some ( decl) = self . lower_eii_extern_target (
164+ * node_id,
165+ // the expect is ok here since we always generate this path in the eii macro.
166+ eii_macro_path. segments . last ( ) . expect ( "at least one segment" ) . ident ,
167+ target,
168+ ) {
169+ EiiImplResolution :: Known ( decl)
170+ } else if let Some ( macro_did) = self . lower_path_simple_eii ( * node_id, eii_macro_path) {
171+ EiiImplResolution :: Macro ( macro_did)
172+ } else {
173+ EiiImplResolution :: Error (
174+ self . dcx ( ) . span_delayed_bug ( * span, "eii never resolved without errors given" ) ,
175+ )
176+ } ;
177+
178+ hir:: attrs:: EiiImpl {
179+ span : self . lower_span ( * span) ,
180+ inner_span : self . lower_span ( * inner_span) ,
181+ impl_marked_unsafe : self . lower_safety ( * impl_safety, hir:: Safety :: Safe ) . is_unsafe ( ) ,
182+ is_default : * is_default,
183+ resolution,
184+ }
185+ }
186+
137187 fn generate_extra_attrs_for_item_kind (
138188 & mut self ,
139189 id : NodeId ,
@@ -143,49 +193,14 @@ impl<'hir> LoweringContext<'_, 'hir> {
143193 ItemKind :: Fn ( box Fn { eii_impls, .. } ) if eii_impls. is_empty ( ) => Vec :: new ( ) ,
144194 ItemKind :: Fn ( box Fn { eii_impls, .. } ) => {
145195 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( ) ,
196+ eii_impls. iter( ) . map( |i| self . lower_eii_impl( i) ) . collect( ) ,
171197 ) ) ]
172198 }
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- } )
199+ ItemKind :: MacroDef ( name, MacroDef { eii_extern_target : Some ( target) , .. } ) => self
200+ . lower_eii_extern_target ( id, * name, target)
201+ . map ( |decl| vec ! [ hir:: Attribute :: Parsed ( AttributeKind :: EiiExternTarget ( decl) ) ] )
188202 . unwrap_or_default ( ) ,
203+
189204 ItemKind :: ExternCrate ( ..)
190205 | ItemKind :: Use ( ..)
191206 | ItemKind :: Static ( ..)
0 commit comments