Skip to content

Commit 8d1d4be

Browse files
committed
Add TyCtx::env_var
1 parent 31766c6 commit 8d1d4be

File tree

7 files changed

+67
-0
lines changed

7 files changed

+67
-0
lines changed

compiler/rustc_codegen_ssa/src/lib.rs

+8
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use rustc_middle::dep_graph::WorkProduct;
3535
use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
3636
use rustc_middle::middle::dependency_format::Dependencies;
3737
use rustc_middle::middle::exported_symbols::SymbolExportKind;
38+
use rustc_middle::ty::TyCtxt;
3839
use rustc_middle::util::Providers;
3940
use rustc_serialize::opaque::{FileEncoder, MemDecoder};
4041
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
@@ -302,3 +303,10 @@ impl CodegenResults {
302303
Ok((codegen_results, outputs))
303304
}
304305
}
306+
307+
/// Tell the `TyCtxt` the environment variables that codegen and linking are
308+
/// going to need.
309+
pub fn register_environment_variables(_tcx: TyCtxt<'_>) {
310+
// FIXME(madsmtm): Add deployment target and SDK root
311+
// https://github.com/rust-lang/rust/pull/129342
312+
}

compiler/rustc_errors/src/diagnostic_impls.rs

+6
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

+3
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

+8
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

+24
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};
@@ -336,6 +337,24 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
336337
)
337338
}
338339

340+
fn env_var(tcx: TyCtxt<'_>, key: Symbol) -> Option<Symbol> {
341+
let var = match std::env::var(key.as_str()) {
342+
Ok(var) => Some(Symbol::intern(&var)),
343+
Err(VarError::NotPresent) => None,
344+
Err(VarError::NotUnicode(var)) => {
345+
tcx.dcx().emit_err(errors::EnvVarNotUnicode { key, var });
346+
None
347+
}
348+
};
349+
// Also add the variable to Cargo's dependency tracking
350+
//
351+
// NOTE: This only works for passes run before `write_dep_info`. See that
352+
// for extension points for configuring environment variables to be
353+
// properly change-tracked.
354+
tcx.sess.psess.env_depinfo.borrow_mut().insert((key, var));
355+
var
356+
}
357+
339358
// Returns all the paths that correspond to generated files.
340359
fn generated_output_paths(
341360
tcx: TyCtxt<'_>,
@@ -647,6 +666,10 @@ pub fn write_dep_info(tcx: TyCtxt<'_>) {
647666
// the side-effect of providing a complete set of all
648667
// accessed files and env vars.
649668
let _ = tcx.resolver_for_lowering();
669+
// Similarly, allow codegen and linking passes to state which environment
670+
// variables they depend on, as those passes are run after this pass, but
671+
// we'll need the information when emitting dependency info to Cargo.
672+
rustc_codegen_ssa::register_environment_variables(tcx);
650673

651674
let sess = tcx.sess;
652675
let _timer = sess.timer("write_dep_info");
@@ -700,6 +723,7 @@ pub static DEFAULT_QUERY_PROVIDERS: LazyLock<Providers> = LazyLock::new(|| {
700723
|tcx, _| tcx.arena.alloc_from_iter(tcx.resolutions(()).stripped_cfg_items.steal());
701724
providers.resolutions = |tcx, ()| tcx.resolver_for_lowering_raw(()).1;
702725
providers.early_lint_checks = early_lint_checks;
726+
providers.env_var = env_var;
703727
proc_macro_decls::provide(providers);
704728
rustc_const_eval::provide(providers);
705729
rustc_middle::hir::provide(providers);

compiler/rustc_middle/src/query/erase.rs

+1
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,7 @@ trivial! {
251251
Option<rustc_span::def_id::DefId>,
252252
Option<rustc_span::def_id::LocalDefId>,
253253
Option<rustc_span::Span>,
254+
Option<rustc_span::Symbol>,
254255
Option<rustc_abi::FieldIdx>,
255256
Option<rustc_target::spec::PanicStrategy>,
256257
Option<usize>,

compiler/rustc_middle/src/query/mod.rs

+17
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, use
131+
/// `rustc_codegen_ssa::register_environment_variables` for that.
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)