diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index 7d9971c021db3..62ed880478b5e 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -1286,8 +1286,7 @@ fn link_sanitizer_runtime( if path.exists() { sess.target_tlib_path.dir.clone() } else { - let default_sysroot = - filesearch::get_or_default_sysroot().expect("Failed finding sysroot"); + let default_sysroot = filesearch::get_or_default_sysroot(); let default_tlib = filesearch::make_target_lib_path(&default_sysroot, sess.opts.target_triple.tuple()); default_tlib diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 6d02d6370fc13..fe0bf7df0b7f6 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -107,8 +107,8 @@ impl From> for TranslationBundleError { /// (overriding any conflicting messages). #[instrument(level = "trace")] pub fn fluent_bundle( - mut user_provided_sysroot: Option, - mut sysroot_candidates: Vec, + sysroot: PathBuf, + sysroot_candidates: Vec, requested_locale: Option, additional_ftl_path: Option<&Path>, with_directionality_markers: bool, @@ -142,7 +142,7 @@ pub fn fluent_bundle( // If the user requests the default locale then don't try to load anything. if let Some(requested_locale) = requested_locale { let mut found_resources = false; - for sysroot in user_provided_sysroot.iter_mut().chain(sysroot_candidates.iter_mut()) { + for mut sysroot in Some(sysroot).into_iter().chain(sysroot_candidates.into_iter()) { sysroot.push("share"); sysroot.push("locale"); sysroot.push(requested_locale.to_string()); diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs index b35703d8e737b..3f87b1a547be5 100644 --- a/compiler/rustc_interface/src/interface.rs +++ b/compiler/rustc_interface/src/interface.rs @@ -18,7 +18,7 @@ use rustc_parse::parser::attr::AllowLeadingUnsafe; use rustc_query_impl::QueryCtxt; use rustc_query_system::query::print_query_stack; use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName}; -use rustc_session::filesearch::{self, sysroot_candidates}; +use rustc_session::filesearch::sysroot_candidates; use rustc_session::parse::ParseSess; use rustc_session::{CompilerIO, EarlyDiagCtxt, Session, lint}; use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMapInputs}; @@ -390,7 +390,7 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se crate::callbacks::setup_callbacks(); - let sysroot = filesearch::materialize_sysroot(config.opts.maybe_sysroot.clone()); + let sysroot = config.opts.sysroot.clone(); let target = config::build_target_config(&early_dcx, &config.opts.target_triple, &sysroot); let file_loader = config.file_loader.unwrap_or_else(|| Box::new(RealFileLoader)); let path_mapping = config.opts.file_path_mapping(); @@ -424,7 +424,7 @@ pub fn run_compiler(config: Config, f: impl FnOnce(&Compiler) -> R + Se let temps_dir = config.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from); let bundle = match rustc_errors::fluent_bundle( - config.opts.maybe_sysroot.clone(), + config.opts.sysroot.clone(), sysroot_candidates().to_vec(), config.opts.unstable_opts.translate_lang.clone(), config.opts.unstable_opts.translate_additional_ftl.as_deref(), diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs index aabd235bcabed..b44be1710edf7 100644 --- a/compiler/rustc_interface/src/tests.rs +++ b/compiler/rustc_interface/src/tests.rs @@ -21,7 +21,7 @@ use rustc_session::config::{ use rustc_session::lint::Level; use rustc_session::search_paths::SearchPath; use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind}; -use rustc_session::{CompilerIO, EarlyDiagCtxt, Session, build_session, filesearch, getopts}; +use rustc_session::{CompilerIO, EarlyDiagCtxt, Session, build_session, getopts}; use rustc_span::edition::{DEFAULT_EDITION, Edition}; use rustc_span::source_map::{RealFileLoader, SourceMapInputs}; use rustc_span::{FileName, SourceFileHashAlgorithm, sym}; @@ -41,7 +41,7 @@ where let matches = optgroups().parse(args).unwrap(); let sessopts = build_session_options(&mut early_dcx, &matches); - let sysroot = filesearch::materialize_sysroot(sessopts.maybe_sysroot.clone()); + let sysroot = sessopts.sysroot.clone(); let target = rustc_session::config::build_target_config(&early_dcx, &sessopts.target_triple, &sysroot); let hash_kind = sessopts.unstable_opts.src_hash_algorithm(&target); diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index 7af221c960757..dcdb7fa9c1054 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -1214,7 +1214,7 @@ impl Default for Options { describe_lints: false, output_types: OutputTypes(BTreeMap::new()), search_paths: vec![], - maybe_sysroot: None, + sysroot: filesearch::materialize_sysroot(None), target_triple: TargetTuple::from_tuple(host_tuple()), test: false, incremental: None, @@ -2618,7 +2618,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M describe_lints, output_types, search_paths, - maybe_sysroot: Some(sysroot), + sysroot, target_triple, test, incremental, diff --git a/compiler/rustc_session/src/filesearch.rs b/compiler/rustc_session/src/filesearch.rs index cc2decc2fe4b3..50f09c57107e6 100644 --- a/compiler/rustc_session/src/filesearch.rs +++ b/compiler/rustc_session/src/filesearch.rs @@ -160,8 +160,7 @@ fn current_dll_path() -> Result { pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> { let target = crate::config::host_tuple(); - let mut sysroot_candidates: SmallVec<[PathBuf; 2]> = - smallvec![get_or_default_sysroot().expect("Failed finding sysroot")]; + let mut sysroot_candidates: SmallVec<[PathBuf; 2]> = smallvec![get_or_default_sysroot()]; let path = current_dll_path().and_then(|s| try_canonicalize(s).map_err(|e| e.to_string())); if let Ok(dll) = path { // use `parent` twice to chop off the file name and then also the @@ -195,12 +194,12 @@ pub fn sysroot_candidates() -> SmallVec<[PathBuf; 2]> { /// Returns the provided sysroot or calls [`get_or_default_sysroot`] if it's none. /// Panics if [`get_or_default_sysroot`] returns an error. pub fn materialize_sysroot(maybe_sysroot: Option) -> PathBuf { - maybe_sysroot.unwrap_or_else(|| get_or_default_sysroot().expect("Failed finding sysroot")) + maybe_sysroot.unwrap_or_else(|| get_or_default_sysroot()) } /// This function checks if sysroot is found using env::args().next(), and if it /// is not found, finds sysroot from current rustc_driver dll. -pub fn get_or_default_sysroot() -> Result { +pub fn get_or_default_sysroot() -> PathBuf { // Follow symlinks. If the resolved path is relative, make it absolute. fn canonicalize(path: PathBuf) -> PathBuf { let path = try_canonicalize(&path).unwrap_or(path); @@ -255,30 +254,25 @@ pub fn get_or_default_sysroot() -> Result { // binary able to locate Rust libraries in systems using content-addressable // storage (CAS). fn from_env_args_next() -> Option { - match env::args_os().next() { - Some(first_arg) => { - let mut p = PathBuf::from(first_arg); - - // Check if sysroot is found using env::args().next() only if the rustc in argv[0] - // is a symlink (see #79253). We might want to change/remove it to conform with - // https://www.gnu.org/prep/standards/standards.html#Finding-Program-Files in the - // future. - if fs::read_link(&p).is_err() { - // Path is not a symbolic link or does not exist. - return None; - } - - // Pop off `bin/rustc`, obtaining the suspected sysroot. - p.pop(); - p.pop(); - // Look for the target rustlib directory in the suspected sysroot. - let mut rustlib_path = rustc_target::relative_target_rustlib_path(&p, "dummy"); - rustlib_path.pop(); // pop off the dummy target. - rustlib_path.exists().then_some(p) - } - None => None, + let mut p = PathBuf::from(env::args_os().next()?); + + // Check if sysroot is found using env::args().next() only if the rustc in argv[0] + // is a symlink (see #79253). We might want to change/remove it to conform with + // https://www.gnu.org/prep/standards/standards.html#Finding-Program-Files in the + // future. + if fs::read_link(&p).is_err() { + // Path is not a symbolic link or does not exist. + return None; } + + // Pop off `bin/rustc`, obtaining the suspected sysroot. + p.pop(); + p.pop(); + // Look for the target rustlib directory in the suspected sysroot. + let mut rustlib_path = rustc_target::relative_target_rustlib_path(&p, "dummy"); + rustlib_path.pop(); // pop off the dummy target. + rustlib_path.exists().then_some(p) } - Ok(from_env_args_next().unwrap_or(default_from_rustc_driver_dll()?)) + from_env_args_next().unwrap_or(default_from_rustc_driver_dll().expect("Failed finding sysroot")) } diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index 8977365ee73d9..804b46a9bec41 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -333,7 +333,7 @@ top_level_options!( output_types: OutputTypes [TRACKED], search_paths: Vec [UNTRACKED], libs: Vec [TRACKED], - maybe_sysroot: Option [UNTRACKED], + sysroot: PathBuf [UNTRACKED], target_triple: TargetTuple [TRACKED], diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index bcd9a73d9d30a..1c9adea281dc7 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -143,7 +143,6 @@ pub struct Session { pub target: Target, pub host: Target, pub opts: config::Options, - pub host_tlib_path: Arc, pub target_tlib_path: Arc, pub psess: ParseSess, pub sysroot: PathBuf, @@ -1042,6 +1041,7 @@ pub fn build_session( let host_triple = config::host_tuple(); let target_triple = sopts.target_triple.tuple(); + // FIXME use host sysroot? let host_tlib_path = Arc::new(SearchPath::from_sysroot_and_triple(&sysroot, host_triple)); let target_tlib_path = if host_triple == target_triple { // Use the same `SearchPath` if host and target triple are identical to avoid unnecessary @@ -1070,7 +1070,6 @@ pub fn build_session( target, host, opts: sopts, - host_tlib_path, target_tlib_path, psess, sysroot, diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs index 9cf471733f94a..23a2bcd9011ee 100644 --- a/src/librustdoc/config.rs +++ b/src/librustdoc/config.rs @@ -103,6 +103,8 @@ pub(crate) struct Options { /// compiling doctests from the crate. pub(crate) edition: Edition, /// The path to the sysroot. Used during the compilation process. + pub(crate) sysroot: PathBuf, + /// Has the same value as `sysroot` except is `None` when the user didn't pass `---sysroot`. pub(crate) maybe_sysroot: Option, /// Lint information passed over the command-line. pub(crate) lint_opts: Vec<(String, Level)>, @@ -202,6 +204,7 @@ impl fmt::Debug for Options { .field("unstable_options", &"...") .field("target", &self.target) .field("edition", &self.edition) + .field("sysroot", &self.sysroot) .field("maybe_sysroot", &self.maybe_sysroot) .field("lint_opts", &self.lint_opts) .field("describe_lints", &self.describe_lints) @@ -729,12 +732,7 @@ impl Options { let target = parse_target_triple(early_dcx, matches); let maybe_sysroot = matches.opt_str("sysroot").map(PathBuf::from); - let sysroot = match &maybe_sysroot { - Some(s) => s.clone(), - None => { - rustc_session::filesearch::get_or_default_sysroot().expect("Failed finding sysroot") - } - }; + let sysroot = rustc_session::filesearch::materialize_sysroot(maybe_sysroot.clone()); let libs = matches .opt_strs("L") @@ -834,6 +832,7 @@ impl Options { unstable_opts_strs, target, edition, + sysroot, maybe_sysroot, lint_opts, describe_lints, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 719f1f978feca..c47e42670c909 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -210,7 +210,7 @@ pub(crate) fn create_config( unstable_opts, target, edition, - maybe_sysroot, + sysroot, lint_opts, describe_lints, lint_cap, @@ -253,7 +253,7 @@ pub(crate) fn create_config( let test = scrape_examples_options.map(|opts| opts.scrape_tests).unwrap_or(false); // plays with error output here! let sessopts = config::Options { - maybe_sysroot, + sysroot, search_paths: libs, crate_types, lint_opts, diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs index 88af9a7388cea..7a9e42933cacb 100644 --- a/src/librustdoc/doctest.rs +++ b/src/librustdoc/doctest.rs @@ -158,7 +158,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, input: Input, options: RustdocOptions if options.proc_macro_crate { vec![CrateType::ProcMacro] } else { vec![CrateType::Rlib] }; let sessopts = config::Options { - maybe_sysroot: options.maybe_sysroot.clone(), + sysroot: options.sysroot.clone(), search_paths: options.libs.clone(), crate_types, lint_opts, diff --git a/tests/ui-fulldeps/run-compiler-twice.rs b/tests/ui-fulldeps/run-compiler-twice.rs index f414c961627dd..ffc19b138a573 100644 --- a/tests/ui-fulldeps/run-compiler-twice.rs +++ b/tests/ui-fulldeps/run-compiler-twice.rs @@ -46,7 +46,7 @@ fn main() { fn compile(code: String, output: PathBuf, sysroot: PathBuf, linker: Option<&Path>) { let mut opts = Options::default(); opts.output_types = OutputTypes::new(&[(OutputType::Exe, None)]); - opts.maybe_sysroot = Some(sysroot); + opts.sysroot = sysroot; if let Some(linker) = linker { opts.cg.linker = Some(linker.to_owned());