Skip to main content

rustc_builtin_macros/
eii.rs

1use rustc_ast::token::{Delimiter, TokenKind};
2use rustc_ast::tokenstream::{DelimSpacing, DelimSpan, Spacing, TokenStream, TokenTree};
3use rustc_ast::{
4    Attribute, DUMMY_NODE_ID, EiiDecl, EiiImpl, ItemKind, MetaItem, Mutability, Path, StmtKind,
5    Visibility, ast,
6};
7use rustc_ast_pretty::pprust::path_to_string;
8use rustc_expand::base::{Annotatable, ExtCtxt};
9use rustc_span::{ErrorGuaranteed, Ident, Span, kw, sym};
10use thin_vec::{ThinVec, thin_vec};
11
12use crate::diagnostics::{
13    EiiAttributeNotSupported, EiiExternTargetExpectedList, EiiExternTargetExpectedMacro,
14    EiiExternTargetExpectedUnsafe, EiiMacroExpectedMaxOneArgument, EiiOnlyOnce,
15    EiiSharedMacroInStatementPosition, EiiSharedMacroTarget, EiiStaticArgumentRequired,
16    EiiStaticDefault, EiiStaticMultipleImplementations, EiiStaticMutable,
17};
18
19/// ```rust
20/// #[eii]
21/// fn panic_handler();
22///
23/// // or:
24///
25/// #[eii(panic_handler)]
26/// fn panic_handler();
27///
28/// // expansion:
29///
30/// extern "Rust" {
31///     fn panic_handler();
32/// }
33///
34/// #[rustc_builtin_macro(eii_shared_macro)]
35/// #[eii_declaration(panic_handler)]
36/// macro panic_handler() {}
37/// ```
38pub(crate) fn eii(
39    ecx: &mut ExtCtxt<'_>,
40    span: Span,
41    meta_item: &ast::MetaItem,
42    item: Annotatable,
43) -> Vec<Annotatable> {
44    eii_(ecx, span, meta_item, item, false)
45}
46
47pub(crate) fn unsafe_eii(
48    ecx: &mut ExtCtxt<'_>,
49    span: Span,
50    meta_item: &ast::MetaItem,
51    item: Annotatable,
52) -> Vec<Annotatable> {
53    eii_(ecx, span, meta_item, item, true)
54}
55
56fn eii_(
57    ecx: &mut ExtCtxt<'_>,
58    eii_attr_span: Span,
59    meta_item: &ast::MetaItem,
60    orig_item: Annotatable,
61    impl_unsafe: bool,
62) -> Vec<Annotatable> {
63    let eii_attr_span = ecx.with_def_site_ctxt(eii_attr_span);
64
65    let item = if let Annotatable::Item(item) = orig_item {
66        item
67    } else if let Annotatable::Stmt(ref stmt) = orig_item
68        && let StmtKind::Item(ref item) = stmt.kind
69        && let ItemKind::Fn(ref f) = item.kind
70    {
71        ecx.dcx().emit_err(EiiSharedMacroInStatementPosition {
72            span: eii_attr_span.to(item.span),
73            name: path_to_string(&meta_item.path),
74            item_span: f.ident.span,
75        });
76        return ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [orig_item]))vec![orig_item];
77    } else {
78        ecx.dcx().emit_err(EiiSharedMacroTarget {
79            span: eii_attr_span,
80            name: path_to_string(&meta_item.path),
81        });
82        return ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [orig_item]))vec![orig_item];
83    };
84
85    let ast::Item { attrs, id: _, span: _, vis, kind, tokens: _ } = item.as_ref();
86    let (item_span, foreign_item_name) = match kind {
87        ItemKind::Fn(func) => (func.sig.span, func.ident),
88        ItemKind::Static(stat) => {
89            // Statics with a default are not supported yet
90            if let Some(stat_body) = &stat.expr {
91                ecx.dcx().emit_err(EiiStaticDefault {
92                    span: stat_body.span,
93                    name: path_to_string(&meta_item.path),
94                });
95                return ::alloc::vec::Vec::new()vec![];
96            }
97            // Statics must have an explicit name for the eii
98            if meta_item.is_word() {
99                ecx.dcx().emit_err(EiiStaticArgumentRequired {
100                    span: eii_attr_span,
101                    name: path_to_string(&meta_item.path),
102                });
103                return ::alloc::vec::Vec::new()vec![];
104            }
105
106            // Mut statics are currently not supported
107            if stat.mutability == Mutability::Mut {
108                ecx.dcx().emit_err(EiiStaticMutable {
109                    span: eii_attr_span,
110                    name: path_to_string(&meta_item.path),
111                });
112            }
113
114            (item.span, stat.ident)
115        }
116        _ => {
117            ecx.dcx().emit_err(EiiSharedMacroTarget {
118                span: eii_attr_span,
119                name: path_to_string(&meta_item.path),
120            });
121            return ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [Annotatable::Item(item)]))vec![Annotatable::Item(item)];
122        }
123    };
124
125    // only clone what we need
126    let attrs = attrs.clone();
127    let vis = vis.clone();
128
129    let attrs_from_decl =
130        filter_attrs_for_multiple_eii_attr(ecx, attrs, eii_attr_span, &meta_item.path);
131    let (macro_attrs, foreign_item_attrs, default_func_attrs) =
132        split_attrs(ecx, item_span, attrs_from_decl);
133
134    let Ok(macro_name) = name_for_impl_macro(ecx, foreign_item_name, &meta_item) else {
135        // we don't need to wrap in Annotatable::Stmt conditionally since
136        // EII can't be used on items in statement position
137        return ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [Annotatable::Item(item)]))vec![Annotatable::Item(item)];
138    };
139
140    let mut module_items = Vec::new();
141
142    if let ItemKind::Fn(func) = kind
143        && func.body.is_some()
144    {
145        module_items.push(generate_default_func_impl(
146            ecx,
147            &func,
148            impl_unsafe,
149            macro_name,
150            eii_attr_span,
151            item_span,
152            foreign_item_name,
153            default_func_attrs,
154        ))
155    }
156
157    module_items.push(generate_foreign_item(
158        ecx,
159        eii_attr_span,
160        item_span,
161        kind,
162        vis,
163        foreign_item_attrs,
164    ));
165    module_items.push(generate_attribute_macro_to_implement(
166        ecx,
167        eii_attr_span,
168        macro_name,
169        foreign_item_name,
170        impl_unsafe,
171        macro_attrs,
172    ));
173
174    // we don't need to wrap in Annotatable::Stmt conditionally since
175    // EII can't be used on items in statement position
176    module_items.into_iter().map(Annotatable::Item).collect()
177}
178
179fn split_attrs(
180    ecx: &mut ExtCtxt<'_>,
181    span: Span,
182    attrs: ThinVec<Attribute>,
183) -> (ThinVec<Attribute>, ThinVec<Attribute>, ThinVec<Attribute>) {
184    let mut macro_attributes = ThinVec::new();
185    let mut foreign_item_attributes = ThinVec::new();
186    let mut default_attributes = ThinVec::new();
187
188    for attr in attrs {
189        match attr.name() {
190            // Inline only matters for the default function being inlined into callsites
191            Some(sym::inline) => default_attributes.push(attr),
192            // If an eii is marked a lang item, that's because we want to call its declaration, so
193            // mark the foreign item as the lang item
194            Some(sym::lang) => foreign_item_attributes.push(attr),
195            // Deprecating an eii means deprecating the macro and the foreign item
196            Some(sym::deprecated) => {
197                foreign_item_attributes.push(attr.clone());
198                macro_attributes.push(attr);
199            }
200            // The stability of an EII affects the usage of the macro and calling the foreign item
201            Some(sym::stable) | Some(sym::unstable) => {
202                foreign_item_attributes.push(attr.clone());
203                macro_attributes.push(attr);
204            }
205            // Doc attributes should be forwarded to the macro and the foreign item, since those are
206            // the two items you interact with as a user.
207            // FIXME: idk yet how EIIs show up in docs, might want to customize
208            _ if attr.is_doc_comment() => {
209                foreign_item_attributes.push(attr.clone());
210                macro_attributes.push(attr);
211            }
212            Some(sym::eii) => {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("should already be filtered out")));
}unreachable!("should already be filtered out"),
213            _ => {
214                ecx.dcx().emit_err(EiiAttributeNotSupported { span, attr_span: attr.span() });
215            }
216        }
217    }
218
219    (macro_attributes, foreign_item_attributes, default_attributes)
220}
221
222/// Decide on the name of the macro that can be used to implement the EII.
223/// This is either an explicitly given name, or the name of the item in the
224/// declaration of the EII.
225fn name_for_impl_macro(
226    ecx: &mut ExtCtxt<'_>,
227    item_ident: Ident,
228    meta_item: &MetaItem,
229) -> Result<Ident, ErrorGuaranteed> {
230    if meta_item.is_word() {
231        Ok(item_ident)
232    } else if let Some([first]) = meta_item.meta_item_list()
233        && let Some(m) = first.meta_item()
234        && m.path.segments.len() == 1
235    {
236        Ok(m.path.segments[0].ident)
237    } else {
238        Err(ecx.dcx().emit_err(EiiMacroExpectedMaxOneArgument {
239            span: meta_item.span,
240            name: path_to_string(&meta_item.path),
241        }))
242    }
243}
244
245/// Ensure that in the list of attrs, there's only a single `eii` attribute.
246fn filter_attrs_for_multiple_eii_attr(
247    ecx: &mut ExtCtxt<'_>,
248    attrs: ThinVec<Attribute>,
249    eii_attr_span: Span,
250    eii_attr_path: &Path,
251) -> ThinVec<Attribute> {
252    attrs
253        .into_iter()
254        .filter(|i| {
255            if i.has_name(sym::eii) {
256                ecx.dcx().emit_err(EiiOnlyOnce {
257                    span: i.span,
258                    first_span: eii_attr_span,
259                    name: path_to_string(eii_attr_path),
260                });
261                false
262            } else {
263                true
264            }
265        })
266        .collect()
267}
268
269fn generate_default_func_impl(
270    ecx: &mut ExtCtxt<'_>,
271    func: &ast::Fn,
272    impl_unsafe: bool,
273    macro_name: Ident,
274    eii_attr_span: Span,
275    item_span: Span,
276    foreign_item_name: Ident,
277    attrs: ThinVec<Attribute>,
278) -> Box<ast::Item> {
279    let mut default_func = func.clone();
280    default_func.eii_impls.push(EiiImpl {
281        node_id: DUMMY_NODE_ID,
282        inner_span: macro_name.span,
283        eii_macro_path: ast::Path::from_ident(macro_name),
284        impl_safety: if impl_unsafe {
285            ast::Safety::Unsafe(eii_attr_span)
286        } else {
287            ast::Safety::Default
288        },
289        span: eii_attr_span,
290        is_default: true,
291        known_eii_macro_resolution: Some(ast::EiiDecl {
292            foreign_item: ecx.path(
293                foreign_item_name.span,
294                // prefix self to explicitly escape the const block generated below
295                // NOTE: this is why EIIs can't be used on statements
296                ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [Ident::from_str_and_span("self", foreign_item_name.span),
                foreign_item_name]))vec![Ident::from_str_and_span("self", foreign_item_name.span), foreign_item_name],
297            ),
298            impl_unsafe,
299        }),
300    });
301
302    let anon_mod = |span: Span, stmts: ThinVec<ast::Stmt>| {
303        let unit = ecx.ty(item_span, ast::TyKind::Tup(ThinVec::new()));
304        let underscore = Ident::new(kw::Underscore, item_span);
305        ecx.item_const(
306            span,
307            underscore,
308            unit,
309            ast::ConstItemRhsKind::new_body(ecx.expr_block(ecx.block(span, stmts))),
310        )
311    };
312
313    // const _: () = {
314    //     <orig fn>
315    // }
316    anon_mod(
317        item_span,
318        {
    let len = [()].len();
    let mut vec = ::thin_vec::ThinVec::with_capacity(len);
    vec.push(ecx.stmt_item(item_span,
            ecx.item(item_span, attrs,
                ItemKind::Fn(Box::new(default_func)))));
    vec
}thin_vec![ecx.stmt_item(
319            item_span,
320            ecx.item(item_span, attrs, ItemKind::Fn(Box::new(default_func)))
321        ),],
322    )
323}
324
325/// Generates a foreign item, like
326///
327/// ```rust, ignore
328/// extern "…" { safe fn item(); }
329/// ```
330fn generate_foreign_item(
331    ecx: &mut ExtCtxt<'_>,
332    eii_attr_span: Span,
333    item_span: Span,
334    item_kind: &ItemKind,
335    vis: Visibility,
336    attrs_from_decl: ThinVec<Attribute>,
337) -> Box<ast::Item> {
338    let mut foreign_item_attrs = attrs_from_decl;
339
340    // Add the rustc_eii_foreign_item on the foreign item. Usually, foreign items are mangled.
341    // This attribute makes sure that we later know that this foreign item's symbol should not be.
342    foreign_item_attrs.push(ecx.attr_word(sym::rustc_eii_foreign_item, eii_attr_span));
343
344    // We set the abi to the default "rust" abi, which can be overridden by `generate_foreign_func`,
345    // if a specific abi was specified on the EII function
346    let mut abi = Some(ast::StrLit {
347        symbol: sym::Rust,
348        suffix: None,
349        symbol_unescaped: sym::Rust,
350        style: ast::StrStyle::Cooked,
351        span: eii_attr_span,
352    });
353    let foreign_kind = match item_kind {
354        ItemKind::Fn(func) => generate_foreign_func(func.clone(), &mut abi),
355        ItemKind::Static(stat) => generate_foreign_static(stat.clone()),
356        _ => {
    ::core::panicking::panic_fmt(format_args!("internal error: entered unreachable code: {0}",
            format_args!("Target was checked earlier")));
}unreachable!("Target was checked earlier"),
357    };
358
359    ecx.item(
360        eii_attr_span,
361        ThinVec::new(),
362        ast::ItemKind::ForeignMod(ast::ForeignMod {
363            extern_span: eii_attr_span,
364            safety: ast::Safety::Unsafe(eii_attr_span),
365            abi,
366            items: From::from([Box::new(ast::ForeignItem {
367                attrs: foreign_item_attrs,
368                id: ast::DUMMY_NODE_ID,
369                span: item_span,
370                vis,
371                kind: foreign_kind,
372                tokens: None,
373            })]),
374        }),
375    )
376}
377
378fn generate_foreign_func(
379    mut func: Box<ast::Fn>,
380    abi: &mut Option<ast::StrLit>,
381) -> ast::ForeignItemKind {
382    match func.sig.header.ext {
383        // extern "X" fn  =>  extern "X" {}
384        ast::Extern::Explicit(lit, _) => *abi = Some(lit),
385        // extern fn  =>  extern {}
386        ast::Extern::Implicit(_) => *abi = None,
387        // no abi was specified, so we keep the default
388        ast::Extern::None => {}
389    };
390
391    // ABI has been moved to the extern {} block, so we remove it from the fn item.
392    func.sig.header.ext = ast::Extern::None;
393    func.body = None;
394
395    // And mark safe functions explicitly as `safe fn`.
396    if func.sig.header.safety == ast::Safety::Default {
397        func.sig.header.safety = ast::Safety::Safe(func.sig.span);
398    }
399
400    ast::ForeignItemKind::Fn(func)
401}
402
403fn generate_foreign_static(mut stat: Box<ast::StaticItem>) -> ast::ForeignItemKind {
404    if stat.safety == ast::Safety::Default {
405        stat.safety = ast::Safety::Safe(stat.ident.span);
406    }
407
408    ast::ForeignItemKind::Static(stat)
409}
410
411/// Generate a stub macro (a bit like in core) that will roughly look like:
412///
413/// ```rust, ignore, example
414/// // Since this a stub macro, the actual code that expands it lives in the compiler.
415/// // This attribute tells the compiler that
416/// #[builtin_macro(eii_shared_macro)]
417/// // the metadata to link this macro to the generated foreign item.
418/// #[eii_declaration(<related_foreign_item>)]
419/// macro macro_name { () => {} }
420/// ```
421fn generate_attribute_macro_to_implement(
422    ecx: &mut ExtCtxt<'_>,
423    span: Span,
424    macro_name: Ident,
425    foreign_item_name: Ident,
426    impl_unsafe: bool,
427    attrs_from_decl: ThinVec<Attribute>,
428) -> Box<ast::Item> {
429    let mut macro_attrs = attrs_from_decl;
430
431    // Avoid "missing stability attribute" errors for eiis in std. See #146993.
432    macro_attrs.push(ecx.attr_name_value_str(sym::rustc_macro_transparency, sym::semiopaque, span));
433
434    // #[builtin_macro(eii_shared_macro)]
435    macro_attrs.push(ecx.attr_nested_word(sym::rustc_builtin_macro, sym::eii_shared_macro, span));
436
437    // cant use ecx methods here to construct item since we need it to be public
438    Box::new(ast::Item {
439        attrs: macro_attrs,
440        id: ast::DUMMY_NODE_ID,
441        span,
442        // pub
443        vis: ast::Visibility { span, kind: ast::VisibilityKind::Public, tokens: None },
444        kind: ast::ItemKind::MacroDef(
445            // macro macro_name
446            macro_name,
447            ast::MacroDef {
448                // { () => {} }
449                body: Box::new(ast::DelimArgs {
450                    dspan: DelimSpan::from_single(span),
451                    delim: Delimiter::Brace,
452                    tokens: TokenStream::from_iter([
453                        TokenTree::Delimited(
454                            DelimSpan::from_single(span),
455                            DelimSpacing::new(Spacing::Alone, Spacing::Alone),
456                            Delimiter::Parenthesis,
457                            TokenStream::default(),
458                        ),
459                        TokenTree::token_alone(TokenKind::FatArrow, span),
460                        TokenTree::Delimited(
461                            DelimSpan::from_single(span),
462                            DelimSpacing::new(Spacing::Alone, Spacing::Alone),
463                            Delimiter::Brace,
464                            TokenStream::default(),
465                        ),
466                    ]),
467                }),
468                macro_rules: false,
469                // #[eii_declaration(foreign_item_ident)]
470                eii_declaration: Some(ast::EiiDecl {
471                    foreign_item: ast::Path::from_ident(foreign_item_name),
472                    impl_unsafe,
473                }),
474            },
475        ),
476        tokens: None,
477    })
478}
479
480pub(crate) fn eii_declaration(
481    ecx: &mut ExtCtxt<'_>,
482    span: Span,
483    meta_item: &ast::MetaItem,
484    mut item: Annotatable,
485) -> Vec<Annotatable> {
486    let i = if let Annotatable::Item(ref mut item) = item {
487        item
488    } else if let Annotatable::Stmt(ref mut stmt) = item
489        && let StmtKind::Item(ref mut item) = stmt.kind
490    {
491        item
492    } else {
493        ecx.dcx().emit_err(EiiExternTargetExpectedMacro { span });
494        return ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [item]))vec![item];
495    };
496
497    let ItemKind::MacroDef(_, d) = &mut i.kind else {
498        ecx.dcx().emit_err(EiiExternTargetExpectedMacro { span });
499        return ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [item]))vec![item];
500    };
501
502    let Some(list) = meta_item.meta_item_list() else {
503        ecx.dcx().emit_err(EiiExternTargetExpectedList { span: meta_item.span });
504        return ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [item]))vec![item];
505    };
506
507    if list.len() > 2 {
508        ecx.dcx().emit_err(EiiExternTargetExpectedList { span: meta_item.span });
509        return ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [item]))vec![item];
510    }
511
512    let Some(extern_item_path) = list.get(0).and_then(|i| i.meta_item()).map(|i| i.path.clone())
513    else {
514        ecx.dcx().emit_err(EiiExternTargetExpectedList { span: meta_item.span });
515        return ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [item]))vec![item];
516    };
517
518    let impl_unsafe = if let Some(i) = list.get(1) {
519        if i.lit().and_then(|i| i.kind.str()).is_some_and(|i| i == kw::Unsafe) {
520            true
521        } else {
522            ecx.dcx().emit_err(EiiExternTargetExpectedUnsafe { span: i.span() });
523            return ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [item]))vec![item];
524        }
525    } else {
526        false
527    };
528
529    d.eii_declaration = Some(EiiDecl { foreign_item: extern_item_path, impl_unsafe });
530
531    // Return the original item and the new methods.
532    ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [item]))vec![item]
533}
534
535/// all Eiis share this function as the implementation for their attribute.
536pub(crate) fn eii_shared_macro(
537    ecx: &mut ExtCtxt<'_>,
538    span: Span,
539    meta_item: &ast::MetaItem,
540    mut item: Annotatable,
541) -> Vec<Annotatable> {
542    let i = if let Annotatable::Item(ref mut item) = item {
543        item
544    } else if let Annotatable::Stmt(ref mut stmt) = item
545        && let StmtKind::Item(ref mut item) = stmt.kind
546    {
547        item
548    } else {
549        ecx.dcx().emit_err(EiiSharedMacroTarget { span, name: path_to_string(&meta_item.path) });
550        return ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [item]))vec![item];
551    };
552
553    let eii_impls = match &mut i.kind {
554        ItemKind::Fn(func) => &mut func.eii_impls,
555        ItemKind::Static(stat) => {
556            if !stat.eii_impls.is_empty() {
557                // Reject multiple implementations on one static item
558                // because it might be unintuitive for libraries defining statics the defined statics may alias
559                ecx.dcx().emit_err(EiiStaticMultipleImplementations { span });
560            }
561            &mut stat.eii_impls
562        }
563        _ => {
564            ecx.dcx()
565                .emit_err(EiiSharedMacroTarget { span, name: path_to_string(&meta_item.path) });
566            return ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [item]))vec![item];
567        }
568    };
569
570    let is_default = if meta_item.is_word() {
571        false
572    } else if let Some([first]) = meta_item.meta_item_list()
573        && let Some(m) = first.meta_item()
574        && m.path.segments.len() == 1
575    {
576        m.path.segments[0].ident.name == kw::Default
577    } else {
578        ecx.dcx().emit_err(EiiMacroExpectedMaxOneArgument {
579            span: meta_item.span,
580            name: path_to_string(&meta_item.path),
581        });
582        return ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [item]))vec![item];
583    };
584
585    eii_impls.push(EiiImpl {
586        node_id: DUMMY_NODE_ID,
587        inner_span: meta_item.path.span,
588        eii_macro_path: meta_item.path.clone(),
589        impl_safety: meta_item.unsafety,
590        span,
591        is_default,
592        known_eii_macro_resolution: None,
593    });
594
595    ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [item]))vec![item]
596}