Skip to content

Commit 1841fb9

Browse files
committed
Auto merge of #74653 - petrochenkov:pmenv, r=dtolnay
proc_macro: Add API for tracked access to environment variables Continuation of #71858. `proc_macro::tracked_env::var` is similar to regular `env::var` called from a proc macro, except that it also adds the accessed variable to depinfo.
2 parents f721fb5 + 62c9fa9 commit 1841fb9

File tree

8 files changed

+66
-0
lines changed

8 files changed

+66
-0
lines changed

src/libproc_macro/bridge/client.rs

+1
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ macro_rules! define_handles {
157157
}
158158
define_handles! {
159159
'owned:
160+
FreeFunctions,
160161
TokenStream,
161162
TokenStreamBuilder,
162163
TokenStreamIter,

src/libproc_macro/bridge/mod.rs

+4
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,10 @@ use std::thread;
5252
macro_rules! with_api {
5353
($S:ident, $self:ident, $m:ident) => {
5454
$m! {
55+
FreeFunctions {
56+
fn drop($self: $S::FreeFunctions);
57+
fn track_env_var(var: &str, value: Option<&str>);
58+
},
5559
TokenStream {
5660
fn drop($self: $S::TokenStream);
5761
fn clone($self: &$S::TokenStream) -> $S::TokenStream;

src/libproc_macro/bridge/server.rs

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ use super::client::HandleStore;
88
/// Declare an associated item of one of the traits below, optionally
99
/// adjusting it (i.e., adding bounds to types and default bodies to methods).
1010
macro_rules! associated_item {
11+
(type FreeFunctions) =>
12+
(type FreeFunctions: 'static;);
1113
(type TokenStream) =>
1214
(type TokenStream: 'static + Clone;);
1315
(type TokenStreamBuilder) =>

src/libproc_macro/lib.rs

+21
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#![feature(decl_macro)]
2525
#![feature(extern_types)]
2626
#![feature(in_band_lifetimes)]
27+
#![feature(inner_deref)]
2728
#![feature(negative_impls)]
2829
#![feature(optin_builtin_traits)]
2930
#![feature(restricted_std)]
@@ -1160,3 +1161,23 @@ impl fmt::Debug for Literal {
11601161
self.0.fmt(f)
11611162
}
11621163
}
1164+
1165+
/// Tracked access to environment variables.
1166+
#[unstable(feature = "proc_macro_tracked_env", issue = "74690")]
1167+
pub mod tracked_env {
1168+
use std::env::{self, VarError};
1169+
use std::ffi::OsStr;
1170+
1171+
/// Retrieve an environment variable and add it to build dependency info.
1172+
/// Build system executing the compiler will know that the variable was accessed during
1173+
/// compilation, and will be able to rerun the build when the value of that variable changes.
1174+
/// Besides the dependency tracking this function should be equivalent to `env::var` from the
1175+
/// standard library, except that the argument must be UTF-8.
1176+
#[unstable(feature = "proc_macro_tracked_env", issue = "74690")]
1177+
pub fn var<K: AsRef<OsStr> + AsRef<str>>(key: K) -> Result<String, VarError> {
1178+
let key: &str = key.as_ref();
1179+
let value = env::var(key);
1180+
crate::bridge::client::FreeFunctions::track_env_var(key, value.as_deref().ok());
1181+
value
1182+
}
1183+
}

src/librustc_expand/proc_macro_server.rs

+9
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,8 @@ impl ToInternal<rustc_errors::Level> for Level {
274274
}
275275
}
276276

277+
pub struct FreeFunctions;
278+
277279
#[derive(Clone)]
278280
pub struct TokenStreamIter {
279281
cursor: tokenstream::Cursor,
@@ -379,6 +381,7 @@ impl<'a> Rustc<'a> {
379381
}
380382

381383
impl server::Types for Rustc<'_> {
384+
type FreeFunctions = FreeFunctions;
382385
type TokenStream = TokenStream;
383386
type TokenStreamBuilder = tokenstream::TokenStreamBuilder;
384387
type TokenStreamIter = TokenStreamIter;
@@ -392,6 +395,12 @@ impl server::Types for Rustc<'_> {
392395
type Span = Span;
393396
}
394397

398+
impl server::FreeFunctions for Rustc<'_> {
399+
fn track_env_var(&mut self, var: &str, value: Option<&str>) {
400+
self.sess.env_depinfo.borrow_mut().insert((Symbol::intern(var), value.map(Symbol::intern)));
401+
}
402+
}
403+
395404
impl server::TokenStream for Rustc<'_> {
396405
fn new(&mut self) -> Self::TokenStream {
397406
TokenStream::default()
+11
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
11
-include ../../run-make-fulldeps/tools.mk
22

3+
# FIXME(eddyb) provide `HOST_RUSTC` and `TARGET_RUSTC`
4+
# instead of hardcoding them everywhere they're needed.
5+
ifeq ($(IS_MUSL_HOST),1)
6+
ADDITIONAL_ARGS := $(RUSTFLAGS)
7+
endif
8+
39
all:
410
EXISTING_ENV=1 EXISTING_OPT_ENV=1 $(RUSTC) --emit dep-info main.rs
511
$(CGREP) "# env-dep:EXISTING_ENV=1" < $(TMPDIR)/main.d
612
$(CGREP) "# env-dep:EXISTING_OPT_ENV=1" < $(TMPDIR)/main.d
713
$(CGREP) "# env-dep:NONEXISTENT_OPT_ENV" < $(TMPDIR)/main.d
814
$(CGREP) "# env-dep:ESCAPE\nESCAPE\\" < $(TMPDIR)/main.d
15+
# Proc macro
16+
$(BARE_RUSTC) $(ADDITIONAL_ARGS) --out-dir $(TMPDIR) macro_def.rs
17+
EXISTING_PROC_MACRO_ENV=1 $(RUSTC) --emit dep-info macro_use.rs
18+
$(CGREP) "# env-dep:EXISTING_PROC_MACRO_ENV=1" < $(TMPDIR)/macro_use.d
19+
$(CGREP) "# env-dep:NONEXISTENT_PROC_MACEO_ENV" < $(TMPDIR)/macro_use.d
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
#![feature(proc_macro_tracked_env)]
2+
#![crate_type = "proc-macro"]
3+
4+
extern crate proc_macro;
5+
use proc_macro::*;
6+
7+
#[proc_macro]
8+
pub fn access_env_vars(_: TokenStream) -> TokenStream {
9+
let _ = tracked_env::var("EXISTING_PROC_MACRO_ENV");
10+
let _ = tracked_env::var("NONEXISTENT_PROC_MACEO_ENV");
11+
TokenStream::new()
12+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#[macro_use]
2+
extern crate macro_def;
3+
4+
access_env_vars!();
5+
6+
fn main() {}

0 commit comments

Comments
 (0)