|
| 1 | +use rustc_ast::expand::allocator::global_fn_name; |
| 2 | +use rustc_ast::{ast, token}; |
| 3 | +use rustc_expand::base::{ExtCtxt, ResolverExpand}; |
| 4 | +use rustc_expand::expand::{AstFragment, ExpansionConfig}; |
| 5 | +use rustc_feature::Features; |
| 6 | +use rustc_session::Session; |
| 7 | +use rustc_session::config::OomStrategy; |
| 8 | +use rustc_span::hygiene::AstPass; |
| 9 | +use rustc_span::{DUMMY_SP, Ident, Symbol, kw, sym}; |
| 10 | +use smallvec::smallvec; |
| 11 | +use thin_vec::thin_vec; |
| 12 | + |
| 13 | +pub fn inject( |
| 14 | + krate: &mut ast::Crate, |
| 15 | + sess: &Session, |
| 16 | + features: &Features, |
| 17 | + resolver: &mut dyn ResolverExpand, |
| 18 | +) { |
| 19 | + if sess.opts.unstable_opts.oom == OomStrategy::Abort { |
| 20 | + // Handled in the allocator shim |
| 21 | + return; |
| 22 | + } |
| 23 | + |
| 24 | + let econfig = ExpansionConfig::default(sym::alloc_error_handler, features); |
| 25 | + let mut ecx = ExtCtxt::new(sess, econfig, resolver, None); |
| 26 | + |
| 27 | + let expn_id = ecx.resolver.expansion_for_ast_pass( |
| 28 | + DUMMY_SP, |
| 29 | + AstPass::OomStrategy, |
| 30 | + &[sym::rustc_attrs], |
| 31 | + None, |
| 32 | + ); |
| 33 | + let sp = DUMMY_SP.with_def_site_ctxt(expn_id.to_expn_id()); |
| 34 | + |
| 35 | + let decl = ecx.fn_decl( |
| 36 | + thin_vec![], |
| 37 | + ast::FnRetTy::Ty( |
| 38 | + ecx.ty(sp, ast::TyKind::Path(None, ecx.path_ident(sp, Ident::new(sym::u8, sp)))), |
| 39 | + ), |
| 40 | + ); |
| 41 | + let sig = ast::FnSig { decl, header: ast::FnHeader::default(), span: sp }; |
| 42 | + let oom_strategy_fn = Box::new(ast::Fn { |
| 43 | + defaultness: ast::Defaultness::Final, |
| 44 | + ident: Ident::new(Symbol::intern(&global_fn_name(OomStrategy::SYMBOL)), sp), |
| 45 | + generics: ast::Generics::default(), |
| 46 | + sig, |
| 47 | + contract: None, |
| 48 | + define_opaque: None, |
| 49 | + body: Some(ecx.block_expr({ |
| 50 | + let suffix = Some(ast::UintTy::U8.name()); |
| 51 | + let lit = token::Lit::new(token::Integer, sym::integer(1), suffix); |
| 52 | + ecx.expr(sp, ast::ExprKind::Lit(lit)) |
| 53 | + })), |
| 54 | + }); |
| 55 | + |
| 56 | + let oom_strategy_item = ecx.item( |
| 57 | + sp, |
| 58 | + thin_vec![ecx.attr_word(sym::rustc_std_internal_symbol, sp)], |
| 59 | + ast::ItemKind::Fn(oom_strategy_fn), |
| 60 | + ); |
| 61 | + |
| 62 | + let items = AstFragment::Items(smallvec![ecx.item_const( |
| 63 | + sp, |
| 64 | + Ident::new(kw::Underscore, sp), |
| 65 | + ecx.ty(sp, ast::TyKind::Tup(thin_vec![])), |
| 66 | + ecx.expr_block(ecx.block(sp, thin_vec![ecx.stmt_item(sp, oom_strategy_item)])), |
| 67 | + )]); |
| 68 | + krate |
| 69 | + .items |
| 70 | + .push(ecx.monotonic_expander().fully_expand_fragment(items).make_items().pop().unwrap()); |
| 71 | +} |
0 commit comments