rustc_builtin_macros/
standard_library_imports.rs
1use rustc_ast::{self as ast, attr};
2use rustc_expand::base::{ExtCtxt, ResolverExpand};
3use rustc_expand::expand::ExpansionConfig;
4use rustc_feature::Features;
5use rustc_session::Session;
6use rustc_span::edition::Edition::*;
7use rustc_span::hygiene::AstPass;
8use rustc_span::{DUMMY_SP, Ident, Symbol, kw, sym};
9use thin_vec::thin_vec;
10
11pub fn inject(
12 krate: &mut ast::Crate,
13 pre_configured_attrs: &[ast::Attribute],
14 resolver: &mut dyn ResolverExpand,
15 sess: &Session,
16 features: &Features,
17) -> usize {
18 let orig_num_items = krate.items.len();
19 let edition = sess.psess.edition;
20
21 let name: Symbol = if attr::contains_name(pre_configured_attrs, sym::no_core) {
23 return 0;
24 } else if attr::contains_name(pre_configured_attrs, sym::no_std) {
25 sym::core
26 } else {
27 sym::std
28 };
29
30 let expn_id = resolver.expansion_for_ast_pass(
31 DUMMY_SP,
32 AstPass::StdImports,
33 &[sym::prelude_import],
34 None,
35 );
36 let span = DUMMY_SP.with_def_site_ctxt(expn_id.to_expn_id());
37 let call_site = DUMMY_SP.with_call_site_ctxt(expn_id.to_expn_id());
38
39 let ecfg = ExpansionConfig::default("std_lib_injection".to_string(), features);
40 let cx = ExtCtxt::new(sess, ecfg, resolver, None);
41
42 let ident_span = if edition >= Edition2018 { span } else { call_site };
43
44 let item = cx.item(
45 span,
46 Ident::new(name, ident_span),
47 thin_vec![cx.attr_word(sym::macro_use, span)],
48 ast::ItemKind::ExternCrate(None),
49 );
50
51 krate.items.insert(0, item);
52
53 let root = (edition == Edition2015).then_some(kw::PathRoot);
54
55 let import_path = root
56 .iter()
57 .chain(&[name, sym::prelude])
58 .chain(&[match edition {
59 Edition2015 => sym::rust_2015,
60 Edition2018 => sym::rust_2018,
61 Edition2021 => sym::rust_2021,
62 Edition2024 => sym::rust_2024,
63 EditionFuture => sym::rust_future,
64 }])
65 .map(|&symbol| Ident::new(symbol, span))
66 .collect();
67
68 let use_item = cx.item(
70 span,
71 Ident::empty(),
72 thin_vec![cx.attr_word(sym::prelude_import, span)],
73 ast::ItemKind::Use(ast::UseTree {
74 prefix: cx.path(span, import_path),
75 kind: ast::UseTreeKind::Glob,
76 span,
77 }),
78 );
79
80 krate.items.insert(0, use_item);
81 krate.items.len() - orig_num_items
82}