1
Fork 0

Rollup merge of #130883 - madsmtm:env-var-query, r=petrochenkov

Add environment variable query

Generally, `rustc` prefers command-line arguments, but in some cases, an environment variable really is the most sensible option. We should make sure that this works properly with the compiler's change-tracking mechanisms, such that changing the relevant environment variable causes a rebuild.

This PR is a first step forwards in doing that.

Part of the work needed to do https://github.com/rust-lang/rust/issues/118204, see https://github.com/rust-lang/rust/pull/129342 for some discussion.

r? ``@petrochenkov``
This commit is contained in:
Stuart Cook 2025-03-27 15:57:21 +11:00 committed by GitHub
commit c45986ae61
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 118 additions and 7 deletions

View file

@ -1,3 +1,4 @@
use std::ffi::OsStr;
use std::intrinsics::transmute_unchecked;
use std::mem::MaybeUninit;
@ -67,6 +68,10 @@ impl<T> EraseType for &'_ [T] {
type Result = [u8; size_of::<&'static [()]>()];
}
impl EraseType for &'_ OsStr {
type Result = [u8; size_of::<&'static OsStr>()];
}
impl<T> EraseType for &'_ ty::List<T> {
type Result = [u8; size_of::<&'static ty::List<()>>()];
}
@ -174,6 +179,10 @@ impl<T> EraseType for Option<&'_ [T]> {
type Result = [u8; size_of::<Option<&'static [()]>>()];
}
impl EraseType for Option<&'_ OsStr> {
type Result = [u8; size_of::<Option<&'static OsStr>>()];
}
impl EraseType for Option<mir::DestructuredConstant<'_>> {
type Result = [u8; size_of::<Option<mir::DestructuredConstant<'static>>>()];
}

View file

@ -1,5 +1,7 @@
//! Defines the set of legal keys that can be used in queries.
use std::ffi::OsStr;
use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalModDefId, ModDefId};
use rustc_hir::hir_id::{HirId, OwnerId};
use rustc_query_system::dep_graph::DepNodeIndex;
@ -498,6 +500,14 @@ impl Key for Option<Symbol> {
}
}
impl<'tcx> Key for &'tcx OsStr {
type Cache<V> = DefaultCache<Self, V>;
fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
DUMMY_SP
}
}
/// Canonical query goals correspond to abstract trait operations that
/// are not tied to any crate in particular.
impl<'tcx, T: Clone> Key for CanonicalQueryInput<'tcx, T> {

View file

@ -6,6 +6,7 @@
#![allow(unused_parens)]
use std::ffi::OsStr;
use std::mem;
use std::path::PathBuf;
use std::sync::Arc;
@ -119,6 +120,21 @@ rustc_queries! {
desc { "perform lints prior to AST lowering" }
}
/// Tracked access to environment variables.
///
/// Useful for the implementation of `std::env!`, `proc-macro`s change
/// detection and other changes in the compiler's behaviour that is easier
/// to control with an environment variable than a flag.
///
/// NOTE: This currently does not work with dependency info in the
/// analysis, codegen and linking passes, place extra code at the top of
/// `rustc_interface::passes::write_dep_info` to make that work.
query env_var_os(key: &'tcx OsStr) -> Option<&'tcx OsStr> {
// Environment variables are global state
eval_always
desc { "get the value of an environment variable" }
}
query resolutions(_: ()) -> &'tcx ty::ResolverGlobalCtxt {
no_hash
desc { "getting the resolver outputs" }

View file

@ -7,6 +7,8 @@ pub mod tls;
use std::assert_matches::{assert_matches, debug_assert_matches};
use std::borrow::Borrow;
use std::cmp::Ordering;
use std::env::VarError;
use std::ffi::OsStr;
use std::hash::{Hash, Hasher};
use std::marker::PhantomData;
use std::ops::{Bound, Deref};
@ -1883,6 +1885,15 @@ impl<'tcx> TyCtxt<'tcx> {
}
None
}
/// Helper to get a tracked environment variable via. [`TyCtxt::env_var_os`] and converting to
/// UTF-8 like [`std::env::var`].
pub fn env_var<K: ?Sized + AsRef<OsStr>>(self, key: &'tcx K) -> Result<&'tcx str, VarError> {
match self.env_var_os(key.as_ref()) {
Some(value) => value.to_str().ok_or_else(|| VarError::NotUnicode(value.to_os_string())),
None => Err(VarError::NotPresent),
}
}
}
impl<'tcx> TyCtxtAt<'tcx> {