2 use rustc_expand::base::{ExtCtxt, ResolverExpand};
3 use rustc_expand::expand::ExpansionConfig;
4 use rustc_session::Session;
5 use rustc_span::edition::Edition::*;
6 use rustc_span::hygiene::AstPass;
7 use rustc_span::symbol::{kw, sym, Ident, Symbol};
8 use rustc_span::DUMMY_SP;
11 mut krate: ast::Crate,
12 resolver: &mut dyn ResolverExpand,
15 let edition = sess.parse_sess.edition;
17 // the first name in this list is the crate name of the crate with the prelude
18 let names: &[Symbol] = if sess.contains_name(&krate.attrs, sym::no_core) {
20 } else if sess.contains_name(&krate.attrs, sym::no_std) {
21 if sess.contains_name(&krate.attrs, sym::compiler_builtins) {
24 &[sym::core, sym::compiler_builtins]
30 let expn_id = resolver.expansion_for_ast_pass(
33 &[sym::prelude_import],
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());
39 let ecfg = ExpansionConfig::default("std_lib_injection".to_string());
40 let cx = ExtCtxt::new(sess, ecfg, resolver, None);
42 // .rev() to preserve ordering above in combination with insert(0, ...)
43 for &name in names.iter().rev() {
44 let ident = if edition >= Edition2018 {
45 Ident::new(name, span)
47 Ident::new(name, call_site)
54 vec![cx.attribute(cx.meta_word(span, sym::macro_use))],
55 ast::ItemKind::ExternCrate(None),
60 // The crates have been injected, the assumption is that the first one is
61 // the one with the prelude.
64 let root = (edition == Edition2015).then(|| kw::PathRoot);
66 let import_path = root
68 .chain(&[name, sym::prelude])
69 .chain(&[match edition {
70 Edition2015 => sym::rust_2015,
71 Edition2018 => sym::rust_2018,
72 Edition2021 => sym::rust_2021,
73 Edition2024 => sym::rust_2024,
75 .map(|&symbol| Ident::new(symbol, span))
78 let use_item = cx.item(
81 vec![cx.attribute(cx.meta_word(span, sym::prelude_import))],
82 ast::ItemKind::Use(ast::UseTree {
83 prefix: cx.path(span, import_path),
84 kind: ast::UseTreeKind::Glob,
89 krate.items.insert(0, use_item);