rustc_builtin_macros/
define_opaque.rs

1use rustc_ast::{DUMMY_NODE_ID, ast};
2use rustc_expand::base::{Annotatable, ExtCtxt};
3use rustc_span::Span;
4
5pub(crate) fn expand(
6    ecx: &mut ExtCtxt<'_>,
7    _expand_span: Span,
8    meta_item: &ast::MetaItem,
9    mut item: Annotatable,
10) -> Vec<Annotatable> {
11    let define_opaque = match &mut item {
12        Annotatable::Item(p) => match &mut p.kind {
13            ast::ItemKind::Fn(f) => Some(&mut f.define_opaque),
14            ast::ItemKind::Const(ct) => Some(&mut ct.define_opaque),
15            ast::ItemKind::Static(si) => Some(&mut si.define_opaque),
16            _ => None,
17        },
18        Annotatable::AssocItem(i, _assoc_ctxt) => match &mut i.kind {
19            ast::AssocItemKind::Fn(func) => Some(&mut func.define_opaque),
20            ast::AssocItemKind::Const(ct) => Some(&mut ct.define_opaque),
21            _ => None,
22        },
23        Annotatable::Stmt(s) => match &mut s.kind {
24            ast::StmtKind::Item(p) => match &mut p.kind {
25                ast::ItemKind::Fn(f) => Some(&mut f.define_opaque),
26                ast::ItemKind::Const(ct) => Some(&mut ct.define_opaque),
27                ast::ItemKind::Static(si) => Some(&mut si.define_opaque),
28                _ => None,
29            },
30            _ => None,
31        },
32        _ => None,
33    };
34
35    let Some(list) = meta_item.meta_item_list() else {
36        ecx.dcx().span_err(meta_item.span, "expected list of type aliases");
37        return vec![item];
38    };
39
40    if let Some(define_opaque) = define_opaque {
41        *define_opaque = Some(
42            list.iter()
43                .filter_map(|entry| match entry {
44                    ast::MetaItemInner::MetaItem(meta_item) if meta_item.is_word() => {
45                        Some((DUMMY_NODE_ID, meta_item.path.clone()))
46                    }
47                    _ => {
48                        ecx.dcx().span_err(entry.span(), "expected path to type alias");
49                        None
50                    }
51                })
52                .collect(),
53        );
54    } else {
55        ecx.dcx().span_err(
56            meta_item.span,
57            "only functions, statics, and consts can define opaque types",
58        );
59    }
60
61    vec![item]
62}