about summary refs log tree commit diff
path: root/compiler/rustc_builtin_macros/src/define_opaque.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_builtin_macros/src/define_opaque.rs')
-rw-r--r--compiler/rustc_builtin_macros/src/define_opaque.rs54
1 files changed, 54 insertions, 0 deletions
diff --git a/compiler/rustc_builtin_macros/src/define_opaque.rs b/compiler/rustc_builtin_macros/src/define_opaque.rs
new file mode 100644
index 00000000000..9777e772cf2
--- /dev/null
+++ b/compiler/rustc_builtin_macros/src/define_opaque.rs
@@ -0,0 +1,54 @@
+use rustc_ast::{DUMMY_NODE_ID, ast};
+use rustc_expand::base::{Annotatable, ExtCtxt};
+use rustc_span::Span;
+
+pub(crate) fn expand(
+    ecx: &mut ExtCtxt<'_>,
+    _expand_span: Span,
+    meta_item: &ast::MetaItem,
+    mut item: Annotatable,
+) -> Vec<Annotatable> {
+    let define_opaque = match &mut item {
+        Annotatable::Item(p) => match &mut p.kind {
+            ast::ItemKind::Fn(f) => Some(&mut f.define_opaque),
+            _ => None,
+        },
+        Annotatable::AssocItem(i, _assoc_ctxt) => match &mut i.kind {
+            ast::AssocItemKind::Fn(func) => Some(&mut func.define_opaque),
+            _ => None,
+        },
+        Annotatable::Stmt(s) => match &mut s.kind {
+            ast::StmtKind::Item(p) => match &mut p.kind {
+                ast::ItemKind::Fn(f) => Some(&mut f.define_opaque),
+                _ => None,
+            },
+            _ => None,
+        },
+        _ => None,
+    };
+
+    let Some(list) = meta_item.meta_item_list() else {
+        ecx.dcx().span_err(meta_item.span, "expected list of type aliases");
+        return vec![item];
+    };
+
+    if let Some(define_opaque) = define_opaque {
+        *define_opaque = Some(
+            list.iter()
+                .filter_map(|entry| match entry {
+                    ast::MetaItemInner::MetaItem(meta_item) if meta_item.is_word() => {
+                        Some((DUMMY_NODE_ID, meta_item.path.clone()))
+                    }
+                    _ => {
+                        ecx.dcx().span_err(entry.span(), "expected path to type alias");
+                        None
+                    }
+                })
+                .collect(),
+        );
+    } else {
+        ecx.dcx().span_err(meta_item.span, "only functions and methods can define opaque types");
+    }
+
+    vec![item]
+}