| 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), |
| ast::ItemKind::Const(ct) => Some(&mut ct.define_opaque), |
| ast::ItemKind::Static(si) => Some(&mut si.define_opaque), |
| _ => None, |
| }, |
| Annotatable::AssocItem(i, _assoc_ctxt) => match &mut i.kind { |
| ast::AssocItemKind::Fn(func) => Some(&mut func.define_opaque), |
| ast::AssocItemKind::Const(ct) => Some(&mut ct.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), |
| ast::ItemKind::Const(ct) => Some(&mut ct.define_opaque), |
| ast::ItemKind::Static(si) => Some(&mut si.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, statics, and consts can define opaque types", |
| ); |
| } |
| |
| vec![item] |
| } |