rustc_builtin_macros/
define_opaque.rs1use 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 _ => None,
15 },
16 Annotatable::AssocItem(i, _assoc_ctxt) => match &mut i.kind {
17 ast::AssocItemKind::Fn(func) => Some(&mut func.define_opaque),
18 _ => None,
19 },
20 Annotatable::Stmt(s) => match &mut s.kind {
21 ast::StmtKind::Item(p) => match &mut p.kind {
22 ast::ItemKind::Fn(f) => Some(&mut f.define_opaque),
23 _ => None,
24 },
25 _ => None,
26 },
27 _ => None,
28 };
29
30 let Some(list) = meta_item.meta_item_list() else {
31 ecx.dcx().span_err(meta_item.span, "expected list of type aliases");
32 return vec![item];
33 };
34
35 if let Some(define_opaque) = define_opaque {
36 *define_opaque = Some(
37 list.iter()
38 .filter_map(|entry| match entry {
39 ast::MetaItemInner::MetaItem(meta_item) if meta_item.is_word() => {
40 Some((DUMMY_NODE_ID, meta_item.path.clone()))
41 }
42 _ => {
43 ecx.dcx().span_err(entry.span(), "expected path to type alias");
44 None
45 }
46 })
47 .collect(),
48 );
49 } else {
50 ecx.dcx().span_err(meta_item.span, "only functions and methods can define opaque types");
51 }
52
53 vec![item]
54}