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