]>
Commit | Line | Data |
---|---|---|
9e0c209e SL |
1 | // The compiler code necessary to support the env! extension. Eventually this |
2 | // should all get sucked into either the compiler syntax extension plugin | |
3 | // interface. | |
4 | // | |
223e47cc | 5 | |
74b04a01 | 6 | use rustc_ast::tokenstream::TokenStream; |
3dfed10e | 7 | use rustc_ast::{self as ast, GenericArg}; |
dfeec247 | 8 | use rustc_expand::base::{self, *}; |
f9f354fc | 9 | use rustc_span::symbol::{kw, sym, Ident, Symbol}; |
dfeec247 | 10 | use rustc_span::Span; |
970d7e83 | 11 | |
85aaf69f | 12 | use std::env; |
223e47cc | 13 | |
dfeec247 XL |
14 | pub fn expand_option_env<'cx>( |
15 | cx: &'cx mut ExtCtxt<'_>, | |
16 | sp: Span, | |
17 | tts: TokenStream, | |
18 | ) -> Box<dyn base::MacResult + 'cx> { | |
5e7ed085 FG |
19 | let Some(var) = get_single_str_from_tts(cx, sp, tts, "option_env!") else { |
20 | return DummyResult::any(sp); | |
1a4d82fc JJ |
21 | }; |
22 | ||
e1599b0c | 23 | let sp = cx.with_def_site_ctxt(sp); |
04454e1e FG |
24 | let value = env::var(var.as_str()).ok().as_deref().map(Symbol::intern); |
25 | cx.sess.parse_sess.env_depinfo.borrow_mut().insert((var, value)); | |
f035d41b XL |
26 | let e = match value { |
27 | None => { | |
e1599b0c | 28 | let lt = cx.lifetime(sp, Ident::new(kw::StaticLifetime, sp)); |
dfeec247 XL |
29 | cx.expr_path(cx.path_all( |
30 | sp, | |
31 | true, | |
32 | cx.std_path(&[sym::option, sym::Option, sym::None]), | |
33 | vec![GenericArg::Type(cx.ty_rptr( | |
34 | sp, | |
35 | cx.ty_ident(sp, Ident::new(sym::str, sp)), | |
36 | Some(lt), | |
37 | ast::Mutability::Not, | |
38 | ))], | |
39 | )) | |
9e0c209e | 40 | } |
f035d41b | 41 | Some(value) => cx.expr_call_global( |
dfeec247 XL |
42 | sp, |
43 | cx.std_path(&[sym::option, sym::Option, sym::Some]), | |
f035d41b | 44 | vec![cx.expr_str(sp, value)], |
dfeec247 | 45 | ), |
1a4d82fc | 46 | }; |
c34b1796 | 47 | MacEager::expr(e) |
1a4d82fc | 48 | } |
223e47cc | 49 | |
dfeec247 XL |
50 | pub fn expand_env<'cx>( |
51 | cx: &'cx mut ExtCtxt<'_>, | |
52 | sp: Span, | |
53 | tts: TokenStream, | |
54 | ) -> Box<dyn base::MacResult + 'cx> { | |
1a4d82fc | 55 | let mut exprs = match get_exprs_from_tts(cx, sp, tts) { |
487cf647 | 56 | Some(exprs) if exprs.is_empty() => { |
1a4d82fc | 57 | cx.span_err(sp, "env! takes 1 or 2 arguments"); |
e1599b0c | 58 | return DummyResult::any(sp); |
1a4d82fc | 59 | } |
e1599b0c | 60 | None => return DummyResult::any(sp), |
9e0c209e | 61 | Some(exprs) => exprs.into_iter(), |
1a4d82fc JJ |
62 | }; |
63 | ||
5e7ed085 FG |
64 | let Some((var, _style)) = expr_to_string(cx, exprs.next().unwrap(), "expected string literal") else { |
65 | return DummyResult::any(sp); | |
1a4d82fc JJ |
66 | }; |
67 | let msg = match exprs.next() { | |
476ff2be | 68 | None => Symbol::intern(&format!("environment variable `{}` not defined", var)), |
dfeec247 XL |
69 | Some(second) => match expr_to_string(cx, second, "expected string literal") { |
70 | None => return DummyResult::any(sp), | |
71 | Some((s, _style)) => s, | |
72 | }, | |
1a4d82fc | 73 | }; |
223e47cc | 74 | |
b7449926 | 75 | if exprs.next().is_some() { |
3157f602 | 76 | cx.span_err(sp, "env! takes 1 or 2 arguments"); |
e1599b0c | 77 | return DummyResult::any(sp); |
1a4d82fc | 78 | } |
223e47cc | 79 | |
f9f354fc | 80 | let sp = cx.with_def_site_ctxt(sp); |
a2a8927a | 81 | let value = env::var(var.as_str()).ok().as_deref().map(Symbol::intern); |
3dfed10e | 82 | cx.sess.parse_sess.env_depinfo.borrow_mut().insert((var, value)); |
f035d41b XL |
83 | let e = match value { |
84 | None => { | |
a2a8927a | 85 | cx.span_err(sp, msg.as_str()); |
e1599b0c | 86 | return DummyResult::any(sp); |
1a4d82fc | 87 | } |
f035d41b | 88 | Some(value) => cx.expr_str(sp, value), |
223e47cc | 89 | }; |
c34b1796 | 90 | MacEager::expr(e) |
223e47cc | 91 | } |