]>
Commit | Line | Data |
---|---|---|
3dfed10e | 1 | use rustc_ast as ast; |
f035d41b | 2 | use rustc_expand::base::{ExtCtxt, ResolverExpand}; |
dfeec247 | 3 | use rustc_expand::expand::ExpansionConfig; |
3dfed10e | 4 | use rustc_session::Session; |
6a06907d | 5 | use rustc_span::edition::Edition::*; |
dfeec247 XL |
6 | use rustc_span::hygiene::AstPass; |
7 | use rustc_span::symbol::{kw, sym, Ident, Symbol}; | |
8 | use rustc_span::DUMMY_SP; | |
9fa01778 | 9 | |
416331ca | 10 | pub fn inject( |
e1599b0c | 11 | mut krate: ast::Crate, |
f035d41b | 12 | resolver: &mut dyn ResolverExpand, |
3dfed10e | 13 | sess: &Session, |
e1599b0c | 14 | alt_std_name: Option<Symbol>, |
fc512014 | 15 | ) -> ast::Crate { |
6a06907d | 16 | let edition = sess.parse_sess.edition; |
b7449926 | 17 | |
83c7162d | 18 | // the first name in this list is the crate name of the crate with the prelude |
3dfed10e | 19 | let names: &[Symbol] = if sess.contains_name(&krate.attrs, sym::no_core) { |
fc512014 | 20 | return krate; |
3dfed10e XL |
21 | } else if sess.contains_name(&krate.attrs, sym::no_std) { |
22 | if sess.contains_name(&krate.attrs, sym::compiler_builtins) { | |
e1599b0c | 23 | &[sym::core] |
83c7162d | 24 | } else { |
e1599b0c | 25 | &[sym::core, sym::compiler_builtins] |
83c7162d | 26 | } |
ff7c6d11 | 27 | } else { |
e1599b0c | 28 | &[sym::std] |
c30ab7b3 | 29 | }; |
1a4d82fc | 30 | |
e1599b0c XL |
31 | let expn_id = resolver.expansion_for_ast_pass( |
32 | DUMMY_SP, | |
33 | AstPass::StdImports, | |
34 | &[sym::prelude_import], | |
35 | None, | |
36 | ); | |
136023e0 XL |
37 | let span = DUMMY_SP.with_def_site_ctxt(expn_id.to_expn_id()); |
38 | let call_site = DUMMY_SP.with_call_site_ctxt(expn_id.to_expn_id()); | |
e1599b0c XL |
39 | |
40 | let ecfg = ExpansionConfig::default("std_lib_injection".to_string()); | |
ba9703b0 | 41 | let cx = ExtCtxt::new(sess, ecfg, resolver, None); |
e1599b0c | 42 | |
83c7162d | 43 | // .rev() to preserve ordering above in combination with insert(0, ...) |
e1599b0c | 44 | for &name in names.iter().rev() { |
6a06907d XL |
45 | let ident = if edition >= Edition2018 { |
46 | Ident::new(name, span) | |
47 | } else { | |
48 | Ident::new(name, call_site) | |
49 | }; | |
50 | krate.items.insert( | |
dfeec247 XL |
51 | 0, |
52 | cx.item( | |
53 | span, | |
54 | ident, | |
55 | vec![cx.attribute(cx.meta_word(span, sym::macro_use))], | |
56 | ast::ItemKind::ExternCrate(alt_std_name), | |
57 | ), | |
58 | ); | |
83c7162d | 59 | } |
ff7c6d11 | 60 | |
e1599b0c XL |
61 | // The crates have been injected, the assumption is that the first one is |
62 | // the one with the prelude. | |
83c7162d XL |
63 | let name = names[0]; |
64 | ||
6a06907d XL |
65 | let root = (edition == Edition2015).then(|| kw::PathRoot); |
66 | ||
67 | let import_path = root | |
68 | .iter() | |
69 | .chain(&[name, sym::prelude]) | |
70 | .chain(&[match edition { | |
71 | Edition2015 => sym::rust_2015, | |
72 | Edition2018 => sym::rust_2018, | |
73 | Edition2021 => sym::rust_2021, | |
74 | }]) | |
75 | .map(|&symbol| Ident::new(symbol, span)) | |
76 | .collect(); | |
3157f602 | 77 | |
e1599b0c XL |
78 | let use_item = cx.item( |
79 | span, | |
f9f354fc | 80 | Ident::invalid(), |
e1599b0c | 81 | vec![cx.attribute(cx.meta_word(span, sym::prelude_import))], |
6a06907d | 82 | ast::ItemKind::Use(ast::UseTree { |
e1599b0c | 83 | prefix: cx.path(span, import_path), |
ff7c6d11 | 84 | kind: ast::UseTreeKind::Glob, |
3b2f2976 | 85 | span, |
6a06907d | 86 | }), |
e1599b0c XL |
87 | ); |
88 | ||
6a06907d | 89 | krate.items.insert(0, use_item); |
3157f602 | 90 | |
fc512014 | 91 | krate |
1a4d82fc | 92 | } |