Skip to content

Commit b00f1e0

Browse files
committed
Add TyCtx::env_var
1 parent e920961 commit b00f1e0

File tree

6 files changed

+58
-0
lines changed

6 files changed

+58
-0
lines changed

compiler/rustc_errors/src/diagnostic_impls.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -242,6 +242,12 @@ impl IntoDiagArg for std::ffi::CString {
242242
}
243243
}
244244

245+
impl IntoDiagArg for std::ffi::OsString {
246+
fn into_diag_arg(self) -> DiagArgValue {
247+
DiagArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned()))
248+
}
249+
}
250+
245251
impl IntoDiagArg for rustc_data_structures::small_c_str::SmallCStr {
246252
fn into_diag_arg(self) -> DiagArgValue {
247253
DiagArgValue::Str(Cow::Owned(self.to_string_lossy().into_owned()))

compiler/rustc_interface/messages.ftl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ interface_cant_emit_mir =
44
interface_emoji_identifier =
55
identifiers cannot contain emoji: `{$ident}`
66
7+
interface_env_var_not_unicode =
8+
cannot read environment variable "{$key}" with value "{$var}", since it contains non-unicode data
9+
710
interface_error_writing_dependencies =
811
error writing dependencies to `{$path}`: {$error}
912

compiler/rustc_interface/src/errors.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::ffi::OsString;
12
use std::io;
23
use std::path::Path;
34

@@ -21,6 +22,13 @@ pub struct EmojiIdentifier {
2122
pub ident: Symbol,
2223
}
2324

25+
#[derive(Diagnostic)]
26+
#[diag(interface_env_var_not_unicode)]
27+
pub struct EnvVarNotUnicode {
28+
pub key: Symbol,
29+
pub var: OsString,
30+
}
31+
2432
#[derive(Diagnostic)]
2533
#[diag(interface_mixed_bin_crate)]
2634
pub struct MixedBinCrate;

compiler/rustc_interface/src/passes.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::any::Any;
2+
use std::env::VarError;
23
use std::ffi::OsString;
34
use std::io::{self, BufWriter, Write};
45
use std::path::{Path, PathBuf};
@@ -321,6 +322,24 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
321322
)
322323
}
323324

325+
fn env_var(tcx: TyCtxt<'_>, key: Symbol) -> Option<Symbol> {
326+
let var = match env::var(key.as_str()) {
327+
Ok(var) => Some(Symbol::intern(&var)),
328+
Err(VarError::NotPresent) => None,
329+
Err(VarError::NotUnicode(var)) => {
330+
tcx.dcx().emit_err(errors::EnvVarNotUnicode { key, var });
331+
None
332+
}
333+
};
334+
// Also add the variable to Cargo's dependency tracking
335+
//
336+
// NOTE: This only works for passes run before `write_dep_info`. See that
337+
// for extension points for configuring environment variables to be
338+
// properly change-tracked.
339+
tcx.sess.psess.env_depinfo.borrow_mut().insert((key, var));
340+
var
341+
}
342+
324343
// Returns all the paths that correspond to generated files.
325344
fn generated_output_paths(
326345
tcx: TyCtxt<'_>,
@@ -632,6 +651,9 @@ pub fn write_dep_info(tcx: TyCtxt<'_>) {
632651
// the side-effect of providing a complete set of all
633652
// accessed files and env vars.
634653
let _ = tcx.resolver_for_lowering();
654+
// Similarly, analysis, codegen and linking should state which environment
655+
// variables they depend on here, as those passes are run after this pass,
656+
// but we'll need the information when emitting dependency info to Cargo.
635657

636658
let sess = tcx.sess;
637659
let _timer = sess.timer("write_dep_info");
@@ -685,6 +707,7 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
685707
|tcx, _| tcx.arena.alloc_from_iter(tcx.resolutions(()).stripped_cfg_items.steal());
686708
providers.resolutions = |tcx, ()| tcx.resolver_for_lowering_raw(()).1;
687709
providers.early_lint_checks = early_lint_checks;
710+
providers.env_var = env_var;
688711
proc_macro_decls::provide(providers);
689712
rustc_const_eval::provide(providers);
690713
rustc_middle::hir::provide(providers);

compiler/rustc_middle/src/query/erase.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ trivial! {
255255
Option<rustc_span::def_id::DefId>,
256256
Option<rustc_span::def_id::LocalDefId>,
257257
Option<rustc_span::Span>,
258+
Option<rustc_span::Symbol>,
258259
Option<rustc_abi::FieldIdx>,
259260
Option<rustc_target::spec::PanicStrategy>,
260261
Option<usize>,

compiler/rustc_middle/src/query/mod.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,23 @@ rustc_queries! {
120120
desc { "perform lints prior to macro expansion" }
121121
}
122122

123+
/// Tracked access to environment variables.
124+
///
125+
/// Useful for the implementation of `std::env!`, `proc-macro`s change
126+
/// detection and other changes in the compiler's behaviour that is easier
127+
/// to control with an environment variable than a flag.
128+
///
129+
/// NOTE: This currently does not work with dependency info in the
130+
/// analysis, codegen and linking passes, place extra code at the top of
131+
/// `rustc_interface::passes::write_dep_info` to make that work.
132+
///
133+
/// Will emit an error and return `None` if the variable is not UTF-8.
134+
query env_var(key: Symbol) -> Option<Symbol> {
135+
// Environment variables are global state
136+
eval_always
137+
desc { "get the value of an environment variable" }
138+
}
139+
123140
query resolutions(_: ()) -> &'tcx ty::ResolverGlobalCtxt {
124141
no_hash
125142
desc { "getting the resolver outputs" }

0 commit comments

Comments
 (0)