From 5db81020006d2920fc9c62ffc0f4322f90bffa04 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Sun, 24 Nov 2024 02:36:21 +0100 Subject: [PATCH] Use OsStr in tracked environment variables --- compiler/rustc_interface/messages.ftl | 3 --- compiler/rustc_interface/src/errors.rs | 8 ------- compiler/rustc_interface/src/passes.rs | 32 +++++++++++++++----------- compiler/rustc_middle/src/query/mod.rs | 5 ++-- 4 files changed, 21 insertions(+), 27 deletions(-) diff --git a/compiler/rustc_interface/messages.ftl b/compiler/rustc_interface/messages.ftl index 7c98f07586350..47dfbc1d7fbf1 100644 --- a/compiler/rustc_interface/messages.ftl +++ b/compiler/rustc_interface/messages.ftl @@ -4,9 +4,6 @@ interface_cant_emit_mir = interface_emoji_identifier = identifiers cannot contain emoji: `{$ident}` -interface_env_var_not_unicode = - cannot read environment variable "{$key}" with value "{$var}", since it contains non-unicode data - interface_error_writing_dependencies = error writing dependencies to `{$path}`: {$error} diff --git a/compiler/rustc_interface/src/errors.rs b/compiler/rustc_interface/src/errors.rs index e7ef7d2f375fa..939980a932fdb 100644 --- a/compiler/rustc_interface/src/errors.rs +++ b/compiler/rustc_interface/src/errors.rs @@ -1,4 +1,3 @@ -use std::ffi::OsString; use std::io; use std::path::Path; @@ -22,13 +21,6 @@ pub struct EmojiIdentifier { pub ident: Symbol, } -#[derive(Diagnostic)] -#[diag(interface_env_var_not_unicode)] -pub struct EnvVarNotUnicode { - pub key: Symbol, - pub var: OsString, -} - #[derive(Diagnostic)] #[diag(interface_mixed_bin_crate)] pub struct MixedBinCrate; diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index d9d82d3f0146e..66431458959d9 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -1,6 +1,5 @@ use std::any::Any; -use std::env::VarError; -use std::ffi::OsString; +use std::ffi::{OsStr, OsString}; use std::io::{self, BufWriter, Write}; use std::path::{Path, PathBuf}; use std::sync::{Arc, LazyLock}; @@ -322,22 +321,29 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) { ) } -fn env_var(tcx: TyCtxt<'_>, key: Symbol) -> Option { - let var = match std::env::var(key.as_str()) { - Ok(var) => Some(Symbol::intern(&var)), - Err(VarError::NotPresent) => None, - Err(VarError::NotUnicode(var)) => { - tcx.dcx().emit_err(errors::EnvVarNotUnicode { key, var }); - None - } - }; +fn env_var<'tcx>(tcx: TyCtxt<'tcx>, key: &'tcx OsStr) -> Option<&'tcx OsStr> { + let value = std::env::var_os(key); + + let value_tcx = value.as_deref().map(|value| { + let encoded_bytes = tcx.arena.alloc_slice(value.as_encoded_bytes()); + debug_assert_eq!(value.as_encoded_bytes(), encoded_bytes); + // SAFETY: The bytes came from `as_encoded_bytes`, and we assume that + // `alloc_slice` is implemented correctly, and passes the same bytes + // back (debug asserted above). + unsafe { OsStr::from_encoded_bytes_unchecked(encoded_bytes) } + }); + // Also add the variable to Cargo's dependency tracking // // NOTE: This only works for passes run before `write_dep_info`. See that // for extension points for configuring environment variables to be // properly change-tracked. - tcx.sess.psess.env_depinfo.borrow_mut().insert((key, var)); - var + tcx.sess.psess.env_depinfo.borrow_mut().insert(( + Symbol::intern(&key.to_string_lossy()), + value.map(|value| Symbol::intern(&value.to_string_lossy())), + )); + + value_tcx } // Returns all the paths that correspond to generated files. diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index e31849426e08c..174be2b80e047 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -6,6 +6,7 @@ #![allow(unused_parens)] +use std::ffi::OsStr; use std::mem; use std::ops::Deref; use std::path::PathBuf; @@ -130,9 +131,7 @@ rustc_queries! { /// 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. - /// - /// Will emit an error and return `None` if the variable is not UTF-8. - query env_var(key: Symbol) -> Option { + query env_var(key: &'tcx OsStr) -> Option<&'tcx OsStr> { // Environment variables are global state eval_always desc { "get the value of an environment variable" }