11use rustc_ast:: token:: { Delimiter , TokenKind } ;
22use rustc_ast:: tokenstream:: { DelimSpacing , DelimSpan , Spacing , TokenStream , TokenTree } ;
33use rustc_ast:: {
4- Attribute , DUMMY_NODE_ID , EiiDecl , EiiImpl , ItemKind , MetaItem , Path , Stmt , StmtKind ,
5- Visibility , ast,
4+ Attribute , DUMMY_NODE_ID , EiiDecl , EiiImpl , ItemKind , MetaItem , Path , StmtKind , Visibility , ast,
65} ;
76use rustc_ast_pretty:: pprust:: path_to_string;
87use rustc_expand:: base:: { Annotatable , ExtCtxt } ;
@@ -12,6 +11,7 @@ use thin_vec::{ThinVec, thin_vec};
1211use crate :: errors:: {
1312 EiiExternTargetExpectedList , EiiExternTargetExpectedMacro , EiiExternTargetExpectedUnsafe ,
1413 EiiMacroExpectedMaxOneArgument , EiiOnlyOnce , EiiSharedMacroExpectedFunction ,
14+ EiiSharedMacroInStatementPosition ,
1515} ;
1616
1717/// ```rust
@@ -55,29 +55,29 @@ fn eii_(
5555 ecx : & mut ExtCtxt < ' _ > ,
5656 eii_attr_span : Span ,
5757 meta_item : & ast:: MetaItem ,
58- item : Annotatable ,
58+ orig_item : Annotatable ,
5959 impl_unsafe : bool ,
6060) -> Vec < Annotatable > {
6161 let eii_attr_span = ecx. with_def_site_ctxt ( eii_attr_span) ;
6262
63- let ( item, wrap_item ) : ( _ , & dyn Fn ( _ ) -> _ ) = if let Annotatable :: Item ( item) = item {
64- ( item, & Annotatable :: Item )
65- } else if let Annotatable :: Stmt ( ref stmt) = item
63+ let item = if let Annotatable :: Item ( item) = orig_item {
64+ item
65+ } else if let Annotatable :: Stmt ( ref stmt) = orig_item
6666 && let StmtKind :: Item ( ref item) = stmt. kind
67+ && let ItemKind :: Fn ( ref f) = item. kind
6768 {
68- ( item. clone ( ) , & |item| {
69- Annotatable :: Stmt ( Box :: new ( Stmt {
70- id : DUMMY_NODE_ID ,
71- kind : StmtKind :: Item ( item) ,
72- span : eii_attr_span,
73- } ) )
74- } )
69+ ecx. dcx ( ) . emit_err ( EiiSharedMacroInStatementPosition {
70+ span : eii_attr_span. to ( item. span ) ,
71+ name : path_to_string ( & meta_item. path ) ,
72+ item_span : f. ident . span ,
73+ } ) ;
74+ return vec ! [ orig_item] ;
7575 } else {
7676 ecx. dcx ( ) . emit_err ( EiiSharedMacroExpectedFunction {
7777 span : eii_attr_span,
7878 name : path_to_string ( & meta_item. path ) ,
7979 } ) ;
80- return vec ! [ item ] ;
80+ return vec ! [ orig_item ] ;
8181 } ;
8282
8383 let ast:: Item { attrs, id : _, span : _, vis, kind : ItemKind :: Fn ( func) , tokens : _ } =
@@ -87,7 +87,7 @@ fn eii_(
8787 span : eii_attr_span,
8888 name : path_to_string ( & meta_item. path ) ,
8989 } ) ;
90- return vec ! [ wrap_item ( item) ] ;
90+ return vec ! [ Annotatable :: Item ( item) ] ;
9191 } ;
9292 // only clone what we need
9393 let attrs = attrs. clone ( ) ;
@@ -98,17 +98,19 @@ fn eii_(
9898 filter_attrs_for_multiple_eii_attr ( ecx, attrs, eii_attr_span, & meta_item. path ) ;
9999
100100 let Ok ( macro_name) = name_for_impl_macro ( ecx, & func, & meta_item) else {
101- return vec ! [ wrap_item( item) ] ;
101+ // we don't need to wrap in Annotatable::Stmt conditionally since
102+ // EII can't be used on items in statement position
103+ return vec ! [ Annotatable :: Item ( item) ] ;
102104 } ;
103105
104106 // span of the declaring item without attributes
105107 let item_span = func. sig . span ;
106108 let foreign_item_name = func. ident ;
107109
108- let mut return_items = Vec :: new ( ) ;
110+ let mut module_items = Vec :: new ( ) ;
109111
110112 if func. body . is_some ( ) {
111- return_items . push ( generate_default_impl (
113+ module_items . push ( generate_default_impl (
112114 ecx,
113115 & func,
114116 impl_unsafe,
@@ -119,15 +121,15 @@ fn eii_(
119121 ) )
120122 }
121123
122- return_items . push ( generate_foreign_item (
124+ module_items . push ( generate_foreign_item (
123125 ecx,
124126 eii_attr_span,
125127 item_span,
126128 func,
127129 vis,
128130 & attrs_from_decl,
129131 ) ) ;
130- return_items . push ( generate_attribute_macro_to_implement (
132+ module_items . push ( generate_attribute_macro_to_implement (
131133 ecx,
132134 eii_attr_span,
133135 macro_name,
@@ -136,7 +138,9 @@ fn eii_(
136138 & attrs_from_decl,
137139 ) ) ;
138140
139- return_items. into_iter ( ) . map ( wrap_item) . collect ( )
141+ // we don't need to wrap in Annotatable::Stmt conditionally since
142+ // EII can't be used on items in statement position
143+ module_items. into_iter ( ) . map ( Annotatable :: Item ) . collect ( )
140144}
141145
142146/// Decide on the name of the macro that can be used to implement the EII.
@@ -213,29 +217,14 @@ fn generate_default_impl(
213217 known_eii_macro_resolution : Some ( ast:: EiiDecl {
214218 foreign_item : ecx. path (
215219 foreign_item_name. span ,
216- // prefix super to escape the `dflt` module generated below
217- vec ! [ Ident :: from_str_and_span( "super" , foreign_item_name. span) , foreign_item_name] ,
220+ // prefix self to explicitly escape the const block generated below
221+ // NOTE: this is why EIIs can't be used on statements
222+ vec ! [ Ident :: from_str_and_span( "self" , foreign_item_name. span) , foreign_item_name] ,
218223 ) ,
219224 impl_unsafe,
220225 } ) ,
221226 } ) ;
222227
223- let item_mod = |span : Span , name : Ident , items : ThinVec < Box < ast:: Item > > | {
224- ecx. item (
225- item_span,
226- ThinVec :: new ( ) ,
227- ItemKind :: Mod (
228- ast:: Safety :: Default ,
229- name,
230- ast:: ModKind :: Loaded (
231- items,
232- ast:: Inline :: Yes ,
233- ast:: ModSpans { inner_span : span, inject_use_span : span } ,
234- ) ,
235- ) ,
236- )
237- } ;
238-
239228 let anon_mod = |span : Span , stmts : ThinVec < ast:: Stmt > | {
240229 let unit = ecx. ty ( item_span, ast:: TyKind :: Tup ( ThinVec :: new ( ) ) ) ;
241230 let underscore = Ident :: new ( kw:: Underscore , item_span) ;
@@ -248,33 +237,13 @@ fn generate_default_impl(
248237 } ;
249238
250239 // const _: () = {
251- // mod dflt {
252- // use super::*;
253- // <orig fn>
254- // }
240+ // <orig fn>
255241 // }
256242 anon_mod (
257243 item_span,
258244 thin_vec ! [ ecx. stmt_item(
259245 item_span,
260- item_mod(
261- item_span,
262- Ident :: from_str_and_span( "dflt" , item_span) ,
263- thin_vec![
264- ecx. item(
265- item_span,
266- thin_vec![ ecx. attr_nested_word( sym:: allow, sym:: unused_imports, item_span) ] ,
267- ItemKind :: Use ( ast:: UseTree {
268- prefix: ast:: Path :: from_ident( Ident :: from_str_and_span(
269- "super" , item_span,
270- ) ) ,
271- kind: ast:: UseTreeKind :: Glob ,
272- span: item_span,
273- } )
274- ) ,
275- ecx. item( item_span, attrs, ItemKind :: Fn ( Box :: new( default_func) ) )
276- ]
277- )
246+ ecx. item( item_span, attrs, ItemKind :: Fn ( Box :: new( default_func) ) )
278247 ) , ] ,
279248 )
280249}
0 commit comments