From 69b2179afe695d1a93b792cfd7c4197ca63ce658 Mon Sep 17 00:00:00 2001 From: Vadim Petrochenkov Date: Sun, 3 May 2020 20:47:51 +0300 Subject: [PATCH] Print accessed env vars as special comments into depinfo files --- src/librustc_builtin_macros/env.rs | 18 ++++++++----- src/librustc_builtin_macros/lib.rs | 1 + src/librustc_interface/passes.rs | 35 +++++++++++++++++++++++++ src/librustc_session/parse.rs | 3 +++ src/test/run-make/env-dep-info/Makefile | 8 ++++++ src/test/run-make/env-dep-info/main.rs | 6 +++++ 6 files changed, 64 insertions(+), 7 deletions(-) create mode 100644 src/test/run-make/env-dep-info/Makefile create mode 100644 src/test/run-make/env-dep-info/main.rs diff --git a/src/librustc_builtin_macros/env.rs b/src/librustc_builtin_macros/env.rs index d769ebb1f5520..6c3a1ce0958ec 100644 --- a/src/librustc_builtin_macros/env.rs +++ b/src/librustc_builtin_macros/env.rs @@ -22,8 +22,10 @@ pub fn expand_option_env<'cx>( }; let sp = cx.with_def_site_ctxt(sp); - let e = match env::var(&var.as_str()) { - Err(..) => { + let value = env::var(&var.as_str()).ok().as_deref().map(Symbol::intern); + cx.parse_sess.env_depinfo.borrow_mut().insert((Symbol::intern(&var), value)); + let e = match value { + None => { let lt = cx.lifetime(sp, Ident::new(kw::StaticLifetime, sp)); cx.expr_path(cx.path_all( sp, @@ -37,10 +39,10 @@ pub fn expand_option_env<'cx>( ))], )) } - Ok(s) => cx.expr_call_global( + Some(value) => cx.expr_call_global( sp, cx.std_path(&[sym::option, sym::Option, sym::Some]), - vec![cx.expr_str(sp, Symbol::intern(&s))], + vec![cx.expr_str(sp, value)], ), }; MacEager::expr(e) @@ -78,12 +80,14 @@ pub fn expand_env<'cx>( } let sp = cx.with_def_site_ctxt(sp); - let e = match env::var(&*var.as_str()) { - Err(_) => { + let value = env::var(&*var.as_str()).ok().as_deref().map(Symbol::intern); + cx.parse_sess.env_depinfo.borrow_mut().insert((var, value)); + let e = match value { + None => { cx.span_err(sp, &msg.as_str()); return DummyResult::any(sp); } - Ok(s) => cx.expr_str(sp, Symbol::intern(&s)), + Some(value) => cx.expr_str(sp, value), }; MacEager::expr(e) } diff --git a/src/librustc_builtin_macros/lib.rs b/src/librustc_builtin_macros/lib.rs index a0f82d65618f4..f56d8a372a73e 100644 --- a/src/librustc_builtin_macros/lib.rs +++ b/src/librustc_builtin_macros/lib.rs @@ -5,6 +5,7 @@ #![feature(bool_to_option)] #![feature(crate_visibility_modifier)] #![feature(decl_macro)] +#![feature(inner_deref)] #![feature(nll)] #![feature(or_patterns)] #![feature(proc_macro_internals)] diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index c06fd91133b5c..5af0ba2afb977 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -540,6 +540,22 @@ fn escape_dep_filename(filename: &FileName) -> String { filename.to_string().replace(" ", "\\ ") } +// Makefile comments only need escaping newlines and `\`. +// The result can be unescaped by anything that can unescape `escape_default` and friends. +fn escape_dep_env(symbol: Symbol) -> String { + let s = symbol.as_str(); + let mut escaped = String::with_capacity(s.len()); + for c in s.chars() { + match c { + '\n' => escaped.push_str(r"\n"), + '\r' => escaped.push_str(r"\r"), + '\\' => escaped.push_str(r"\\"), + _ => escaped.push(c), + } + } + escaped +} + fn write_out_deps( sess: &Session, boxed_resolver: &Steal>>, @@ -592,6 +608,25 @@ fn write_out_deps( for path in files { writeln!(file, "{}:", path)?; } + + // Emit special comments with information about accessed environment variables. + let env_depinfo = sess.parse_sess.env_depinfo.borrow(); + if !env_depinfo.is_empty() { + let mut envs: Vec<_> = env_depinfo + .iter() + .map(|(k, v)| (escape_dep_env(*k), v.map(escape_dep_env))) + .collect(); + envs.sort_unstable(); + writeln!(file)?; + for (k, v) in envs { + write!(file, "# env-dep:{}", k)?; + if let Some(v) = v { + write!(file, "={}", v)?; + } + writeln!(file)?; + } + } + Ok(()) })(); diff --git a/src/librustc_session/parse.rs b/src/librustc_session/parse.rs index 233761dbed7de..aaae5889117ed 100644 --- a/src/librustc_session/parse.rs +++ b/src/librustc_session/parse.rs @@ -135,6 +135,8 @@ pub struct ParseSess { pub symbol_gallery: SymbolGallery, /// The parser has reached `Eof` due to an unclosed brace. Used to silence unnecessary errors. pub reached_eof: Lock, + /// Environment variables accessed during the build and their values when they exist. + pub env_depinfo: Lock)>>, } impl ParseSess { @@ -160,6 +162,7 @@ impl ParseSess { gated_spans: GatedSpans::default(), symbol_gallery: SymbolGallery::default(), reached_eof: Lock::new(false), + env_depinfo: Default::default(), } } diff --git a/src/test/run-make/env-dep-info/Makefile b/src/test/run-make/env-dep-info/Makefile new file mode 100644 index 0000000000000..2be0b4b324b08 --- /dev/null +++ b/src/test/run-make/env-dep-info/Makefile @@ -0,0 +1,8 @@ +-include ../../run-make-fulldeps/tools.mk + +all: + EXISTING_ENV=1 EXISTING_OPT_ENV=1 $(RUSTC) --emit dep-info main.rs + $(CGREP) "# env-dep:EXISTING_ENV=1" < $(TMPDIR)/main.d + $(CGREP) "# env-dep:EXISTING_OPT_ENV=1" < $(TMPDIR)/main.d + $(CGREP) "# env-dep:NONEXISTENT_OPT_ENV" < $(TMPDIR)/main.d + $(CGREP) "# env-dep:ESCAPE\nESCAPE\\" < $(TMPDIR)/main.d diff --git a/src/test/run-make/env-dep-info/main.rs b/src/test/run-make/env-dep-info/main.rs new file mode 100644 index 0000000000000..a25246bac792c --- /dev/null +++ b/src/test/run-make/env-dep-info/main.rs @@ -0,0 +1,6 @@ +fn main() { + env!("EXISTING_ENV"); + option_env!("EXISTING_OPT_ENV"); + option_env!("NONEXISTENT_OPT_ENV"); + option_env!("ESCAPE\nESCAPE\\"); +}