Skip to content

Commit 65f0253

Browse files
committed
Support environment variable for interned Symbol value
1 parent 726a43c commit 65f0253

File tree

2 files changed

+58
-4
lines changed

2 files changed

+58
-4
lines changed

compiler/rustc_macros/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#![feature(never_type)]
55
#![feature(proc_macro_diagnostic)]
66
#![feature(proc_macro_span)]
7+
#![feature(proc_macro_tracked_env)]
78
#![allow(rustc::default_hash_types)]
89
#![deny(rustc::untranslatable_diagnostic)]
910
#![deny(rustc::diagnostic_outside_of_impl)]

compiler/rustc_macros/src/symbols.rs

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ use proc_macro2::{Span, TokenStream};
2626
use quote::quote;
2727
use std::collections::HashMap;
2828
use syn::parse::{Parse, ParseStream, Result};
29-
use syn::{braced, punctuated::Punctuated, Ident, LitStr, Token};
29+
use syn::{braced, punctuated::Punctuated, Expr, Ident, Lit, LitStr, Token};
3030

3131
#[cfg(test)]
3232
mod tests;
@@ -59,6 +59,7 @@ struct Symbol {
5959
enum Value {
6060
SameAsName,
6161
String(LitStr),
62+
Env(LitStr),
6263
}
6364

6465
impl Parse for Symbol {
@@ -73,8 +74,27 @@ impl Parse for Symbol {
7374

7475
impl Parse for Value {
7576
fn parse(input: ParseStream<'_>) -> Result<Self> {
76-
let lit: LitStr = input.parse()?;
77-
Ok(Value::String(lit))
77+
let expr: Expr = input.parse()?;
78+
match &expr {
79+
Expr::Lit(expr) => {
80+
if let Lit::Str(lit) = &expr.lit {
81+
return Ok(Value::String(lit.clone()));
82+
}
83+
}
84+
Expr::Macro(expr) => {
85+
if expr.mac.path.is_ident("env") && let Ok(lit) = expr.mac.parse_body() {
86+
return Ok(Value::Env(lit));
87+
}
88+
}
89+
_ => {}
90+
}
91+
Err(syn::Error::new_spanned(
92+
expr,
93+
concat!(
94+
"unsupported expression for symbol value; implement support for this in ",
95+
file!(),
96+
),
97+
))
7898
}
7999
}
80100

@@ -198,12 +218,14 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
198218
// Generate the listed symbols.
199219
for symbol in input.symbols.iter() {
200220
let name = &symbol.name;
221+
check_order(symbol.name.span(), &name.to_string(), &mut errors);
222+
201223
let value = match &symbol.value {
202224
Value::SameAsName => name.to_string(),
203225
Value::String(lit) => lit.value(),
226+
Value::Env(_) => continue,
204227
};
205228
let idx = entries.insert(symbol.name.span(), &value, &mut errors);
206-
check_order(symbol.name.span(), &name.to_string(), &mut errors);
207229

208230
prefill_stream.extend(quote! {
209231
#value,
@@ -222,6 +244,37 @@ fn symbols_with_errors(input: TokenStream) -> (TokenStream, Vec<syn::Error>) {
222244
});
223245
}
224246

247+
// Symbols whose value comes from an environment variable. It's allowed for
248+
// these to have the same value as another symbol.
249+
for symbol in &input.symbols {
250+
let env_var = match &symbol.value {
251+
Value::Env(lit) => lit,
252+
_ => continue,
253+
};
254+
255+
let value = match proc_macro::tracked_env::var(env_var.value()) {
256+
Ok(value) => value,
257+
Err(err) => {
258+
errors.error(symbol.name.span(), err.to_string());
259+
continue;
260+
}
261+
};
262+
263+
let idx = if let Some(prev) = entries.map.get(&value) {
264+
prev.idx
265+
} else {
266+
prefill_stream.extend(quote! {
267+
#value,
268+
});
269+
entries.insert(symbol.name.span(), &value, &mut errors)
270+
};
271+
272+
let name = &symbol.name;
273+
symbols_stream.extend(quote! {
274+
pub const #name: Symbol = Symbol::new(#idx);
275+
});
276+
}
277+
225278
let symbol_digits_base = entries.map["0"].idx;
226279
let preinterned_symbols_count = entries.len();
227280
let output = quote! {

0 commit comments

Comments
 (0)