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 { 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] }