Skip to content

Commit 6ef6835

Browse files
committed
rustc_session: Add a structure for keeping both explicit and default sysroots
Also avoid creating and cloning sysroot unnecessarily.
1 parent 42245d3 commit 6ef6835

File tree

18 files changed

+94
-97
lines changed

18 files changed

+94
-97
lines changed

Cargo.lock

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3655,7 +3655,6 @@ dependencies = [
36553655
"rustc_macros",
36563656
"rustc_serialize",
36573657
"rustc_span",
3658-
"smallvec",
36593658
"tracing",
36603659
"unic-langid",
36613660
]
@@ -4446,7 +4445,6 @@ dependencies = [
44464445
"rustc_serialize",
44474446
"rustc_span",
44484447
"rustc_target",
4449-
"smallvec",
44504448
"termize",
44514449
"tracing",
44524450
"windows",

compiler/rustc_codegen_ssa/src/back/link.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,7 @@ fn link_natively(
865865
command: cmd,
866866
escaped_output,
867867
verbose: sess.opts.verbose,
868-
sysroot_dir: sess.sysroot.clone(),
868+
sysroot_dir: sess.opts.sysroot.path().to_owned(),
869869
};
870870
sess.dcx().emit_err(err);
871871
// If MSVC's `link.exe` was expected but the return code
@@ -1249,10 +1249,10 @@ fn link_sanitizer_runtime(
12491249
if path.exists() {
12501250
sess.target_tlib_path.dir.clone()
12511251
} else {
1252-
let default_sysroot = filesearch::get_or_default_sysroot();
1253-
let default_tlib =
1254-
filesearch::make_target_lib_path(&default_sysroot, sess.opts.target_triple.tuple());
1255-
default_tlib
1252+
filesearch::make_target_lib_path(
1253+
&sess.opts.sysroot.default,
1254+
sess.opts.target_triple.tuple(),
1255+
)
12561256
}
12571257
}
12581258

@@ -1758,7 +1758,7 @@ fn detect_self_contained_mingw(sess: &Session, linker: &Path) -> bool {
17581758
for dir in env::split_paths(&env::var_os("PATH").unwrap_or_default()) {
17591759
let full_path = dir.join(&linker_with_extension);
17601760
// If linker comes from sysroot assume self-contained mode
1761-
if full_path.is_file() && !full_path.starts_with(&sess.sysroot) {
1761+
if full_path.is_file() && !full_path.starts_with(sess.opts.sysroot.path()) {
17621762
return false;
17631763
}
17641764
}

compiler/rustc_codegen_ssa/src/back/linker.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1059,7 +1059,7 @@ impl<'a> Linker for MsvcLinker<'a> {
10591059
self.link_arg("/PDBALTPATH:%_PDB%");
10601060

10611061
// This will cause the Microsoft linker to embed .natvis info into the PDB file
1062-
let natvis_dir_path = self.sess.sysroot.join("lib\\rustlib\\etc");
1062+
let natvis_dir_path = self.sess.opts.sysroot.path().join("lib\\rustlib\\etc");
10631063
if let Ok(natvis_dir) = fs::read_dir(&natvis_dir_path) {
10641064
for entry in natvis_dir {
10651065
match entry {

compiler/rustc_driver_impl/src/lib.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,13 +53,13 @@ use rustc_metadata::locator;
5353
use rustc_middle::ty::TyCtxt;
5454
use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
5555
use rustc_session::config::{
56-
CG_OPTIONS, CrateType, ErrorOutputType, Input, OptionDesc, OutFileName, OutputType,
56+
CG_OPTIONS, CrateType, ErrorOutputType, Input, OptionDesc, OutFileName, OutputType, Sysroot,
5757
UnstableOptions, Z_OPTIONS, nightly_options, parse_target_triple,
5858
};
5959
use rustc_session::getopts::{self, Matches};
6060
use rustc_session::lint::{Lint, LintId};
6161
use rustc_session::output::{CRATE_TYPES, collect_crate_types, invalid_output_for_target};
62-
use rustc_session::{EarlyDiagCtxt, Session, config, filesearch};
62+
use rustc_session::{EarlyDiagCtxt, Session, config};
6363
use rustc_span::FileName;
6464
use rustc_span::def_id::LOCAL_CRATE;
6565
use rustc_target::json::ToJson;
@@ -662,7 +662,7 @@ fn print_crate_info(
662662
println_info!("{}", targets.join("\n"));
663663
}
664664
HostTuple => println_info!("{}", rustc_session::config::host_tuple()),
665-
Sysroot => println_info!("{}", sess.sysroot.display()),
665+
Sysroot => println_info!("{}", sess.opts.sysroot.path().display()),
666666
TargetLibdir => println_info!("{}", sess.target_tlib_path.dir.display()),
667667
TargetSpecJson => {
668668
println_info!("{}", serde_json::to_string_pretty(&sess.target.to_json()).unwrap());
@@ -1114,8 +1114,8 @@ fn get_backend_from_raw_matches(
11141114
let debug_flags = matches.opt_strs("Z");
11151115
let backend_name = debug_flags.iter().find_map(|x| x.strip_prefix("codegen-backend="));
11161116
let target = parse_target_triple(early_dcx, matches);
1117-
let sysroot = filesearch::materialize_sysroot(matches.opt_str("sysroot").map(PathBuf::from));
1118-
let target = config::build_target_config(early_dcx, &target, &sysroot);
1117+
let sysroot = Sysroot::new(matches.opt_str("sysroot").map(PathBuf::from));
1118+
let target = config::build_target_config(early_dcx, &target, sysroot.path());
11191119

11201120
get_codegen_backend(early_dcx, &sysroot, backend_name, &target)
11211121
}

compiler/rustc_error_messages/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ rustc_data_structures = { path = "../rustc_data_structures" }
1616
rustc_macros = { path = "../rustc_macros" }
1717
rustc_serialize = { path = "../rustc_serialize" }
1818
rustc_span = { path = "../rustc_span" }
19-
smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
2019
tracing = "0.1"
2120
unic-langid = { version = "0.9.0", features = ["macros"] }
2221
# tidy-alphabetical-end

compiler/rustc_error_messages/src/lib.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
// tidy-alphabetical-start
22
#![allow(internal_features)]
33
#![doc(rust_logo)]
4+
#![feature(anonymous_lifetime_in_impl_trait)]
45
#![feature(rustc_attrs)]
56
#![feature(rustdoc_internals)]
67
#![feature(type_alias_impl_trait)]
78
// tidy-alphabetical-end
89

910
use std::borrow::Cow;
1011
use std::error::Error;
11-
use std::path::{Path, PathBuf};
12+
use std::path::Path;
1213
use std::sync::{Arc, LazyLock};
1314
use std::{fmt, fs, io};
1415

@@ -21,7 +22,6 @@ use intl_memoizer::concurrent::IntlLangMemoizer;
2122
use rustc_data_structures::sync::{DynSend, IntoDynSyncSend};
2223
use rustc_macros::{Decodable, Encodable};
2324
use rustc_span::Span;
24-
use smallvec::SmallVec;
2525
use tracing::{instrument, trace};
2626
pub use unic_langid::{LanguageIdentifier, langid};
2727

@@ -107,7 +107,7 @@ impl From<Vec<FluentError>> for TranslationBundleError {
107107
/// (overriding any conflicting messages).
108108
#[instrument(level = "trace")]
109109
pub fn fluent_bundle(
110-
sysroot_candidates: SmallVec<[PathBuf; 2]>,
110+
sysroot_candidates: &[&Path],
111111
requested_locale: Option<LanguageIdentifier>,
112112
additional_ftl_path: Option<&Path>,
113113
with_directionality_markers: bool,
@@ -141,7 +141,8 @@ pub fn fluent_bundle(
141141
// If the user requests the default locale then don't try to load anything.
142142
if let Some(requested_locale) = requested_locale {
143143
let mut found_resources = false;
144-
for mut sysroot in sysroot_candidates {
144+
for sysroot in sysroot_candidates {
145+
let mut sysroot = sysroot.to_path_buf();
145146
sysroot.push("share");
146147
sysroot.push("locale");
147148
sysroot.push(requested_locale.to_string());

compiler/rustc_interface/src/interface.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ use rustc_parse::parser::attr::AllowLeadingUnsafe;
1818
use rustc_query_impl::QueryCtxt;
1919
use rustc_query_system::query::print_query_stack;
2020
use rustc_session::config::{self, Cfg, CheckCfg, ExpectedValues, Input, OutFileName};
21-
use rustc_session::filesearch::sysroot_with_fallback;
2221
use rustc_session::parse::ParseSess;
2322
use rustc_session::{CompilerIO, EarlyDiagCtxt, Session, lint};
2423
use rustc_span::source_map::{FileLoader, RealFileLoader, SourceMapInputs};
@@ -405,8 +404,11 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
405404

406405
crate::callbacks::setup_callbacks();
407406

408-
let sysroot = config.opts.sysroot.clone();
409-
let target = config::build_target_config(&early_dcx, &config.opts.target_triple, &sysroot);
407+
let target = config::build_target_config(
408+
&early_dcx,
409+
&config.opts.target_triple,
410+
config.opts.sysroot.path(),
411+
);
410412
let file_loader = config.file_loader.unwrap_or_else(|| Box::new(RealFileLoader));
411413
let path_mapping = config.opts.file_path_mapping();
412414
let hash_kind = config.opts.unstable_opts.src_hash_algorithm(&target);
@@ -426,7 +428,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
426428
let codegen_backend = match config.make_codegen_backend {
427429
None => util::get_codegen_backend(
428430
&early_dcx,
429-
&sysroot,
431+
&config.opts.sysroot,
430432
config.opts.unstable_opts.codegen_backend.as_deref(),
431433
&target,
432434
),
@@ -440,7 +442,7 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
440442
let temps_dir = config.opts.unstable_opts.temps_dir.as_deref().map(PathBuf::from);
441443

442444
let bundle = match rustc_errors::fluent_bundle(
443-
sysroot_with_fallback(&config.opts.sysroot),
445+
&config.opts.sysroot.all_paths().collect::<Vec<_>>(),
444446
config.opts.unstable_opts.translate_lang.clone(),
445447
config.opts.unstable_opts.translate_additional_ftl.as_deref(),
446448
config.opts.unstable_opts.translate_directionality_markers,
@@ -469,7 +471,6 @@ pub fn run_compiler<R: Send>(config: Config, f: impl FnOnce(&Compiler) -> R + Se
469471
locale_resources,
470472
config.lint_caps,
471473
target,
472-
sysroot,
473474
util::rustc_version_str().unwrap_or("unknown"),
474475
config.ice_file,
475476
config.using_internal_features,

compiler/rustc_interface/src/tests.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,11 @@ where
4141

4242
let matches = optgroups().parse(args).unwrap();
4343
let sessopts = build_session_options(&mut early_dcx, &matches);
44-
let sysroot = sessopts.sysroot.clone();
45-
let target =
46-
rustc_session::config::build_target_config(&early_dcx, &sessopts.target_triple, &sysroot);
44+
let target = rustc_session::config::build_target_config(
45+
&early_dcx,
46+
&sessopts.target_triple,
47+
sessopts.sysroot.path(),
48+
);
4749
let hash_kind = sessopts.unstable_opts.src_hash_algorithm(&target);
4850
let checksum_hash_kind = sessopts.unstable_opts.checksum_hash_algorithm();
4951
let sm_inputs = Some(SourceMapInputs {
@@ -72,7 +74,6 @@ where
7274
vec![],
7375
Default::default(),
7476
target,
75-
sysroot,
7677
"",
7778
None,
7879
&USING_INTERNAL_FEATURES,

compiler/rustc_interface/src/util.rs

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_data_structures::sync;
1111
use rustc_metadata::{DylibError, load_symbol_from_dylib};
1212
use rustc_middle::ty::CurrentGcx;
1313
use rustc_parse::validate_attr;
14-
use rustc_session::config::{Cfg, OutFileName, OutputFilenames, OutputTypes, host_tuple};
14+
use rustc_session::config::{Cfg, OutFileName, OutputFilenames, OutputTypes, Sysroot, host_tuple};
1515
use rustc_session::lint::{self, BuiltinLintDiag, LintBuffer};
1616
use rustc_session::output::{CRATE_TYPES, categorize_crate_type};
1717
use rustc_session::{EarlyDiagCtxt, Session, filesearch};
@@ -305,7 +305,7 @@ fn load_backend_from_dylib(early_dcx: &EarlyDiagCtxt, path: &Path) -> MakeBacken
305305
/// A name of `None` indicates that the default backend should be used.
306306
pub fn get_codegen_backend(
307307
early_dcx: &EarlyDiagCtxt,
308-
sysroot: &Path,
308+
sysroot: &Sysroot,
309309
backend_name: Option<&str>,
310310
target: &Target,
311311
) -> Box<dyn CodegenBackend> {
@@ -336,25 +336,24 @@ pub fn get_codegen_backend(
336336
// This is used for rustdoc, but it uses similar machinery to codegen backend
337337
// loading, so we leave the code here. It is potentially useful for other tools
338338
// that want to invoke the rustc binary while linking to rustc as well.
339-
pub fn rustc_path<'a>() -> Option<&'a Path> {
339+
pub fn rustc_path<'a>(sysroot: &Sysroot) -> Option<&'a Path> {
340340
static RUSTC_PATH: OnceLock<Option<PathBuf>> = OnceLock::new();
341341

342-
const BIN_PATH: &str = env!("RUSTC_INSTALL_BINDIR");
343-
344-
RUSTC_PATH.get_or_init(|| get_rustc_path_inner(BIN_PATH)).as_deref()
345-
}
346-
347-
fn get_rustc_path_inner(bin_path: &str) -> Option<PathBuf> {
348-
let candidate = filesearch::get_or_default_sysroot()
349-
.join(bin_path)
350-
.join(if cfg!(target_os = "windows") { "rustc.exe" } else { "rustc" });
351-
candidate.exists().then_some(candidate)
342+
RUSTC_PATH
343+
.get_or_init(|| {
344+
let candidate = sysroot
345+
.default
346+
.join(env!("RUSTC_INSTALL_BINDIR"))
347+
.join(if cfg!(target_os = "windows") { "rustc.exe" } else { "rustc" });
348+
candidate.exists().then_some(candidate)
349+
})
350+
.as_deref()
352351
}
353352

354353
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
355354
fn get_codegen_sysroot(
356355
early_dcx: &EarlyDiagCtxt,
357-
sysroot: &Path,
356+
sysroot: &Sysroot,
358357
backend_name: &str,
359358
) -> MakeBackendFn {
360359
// For now we only allow this function to be called once as it'll dlopen a
@@ -369,10 +368,9 @@ fn get_codegen_sysroot(
369368
);
370369

371370
let target = host_tuple();
372-
let sysroot_candidates = filesearch::sysroot_with_fallback(&sysroot);
373371

374-
let sysroot = sysroot_candidates
375-
.iter()
372+
let sysroot = sysroot
373+
.all_paths()
376374
.map(|sysroot| {
377375
filesearch::make_target_lib_path(sysroot, target).with_file_name("codegen-backends")
378376
})
@@ -381,8 +379,8 @@ fn get_codegen_sysroot(
381379
f.exists()
382380
})
383381
.unwrap_or_else(|| {
384-
let candidates = sysroot_candidates
385-
.iter()
382+
let candidates = sysroot
383+
.all_paths()
386384
.map(|p| p.display().to_string())
387385
.collect::<Vec<_>>()
388386
.join("\n* ");

compiler/rustc_metadata/src/locator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ impl<'a> CrateLocator<'a> {
321321

322322
CrateLocator {
323323
only_needs_metadata,
324-
sysroot: &sess.sysroot,
324+
sysroot: sess.opts.sysroot.path(),
325325
metadata_loader,
326326
cfg_version: sess.cfg_version,
327327
crate_name,

compiler/rustc_session/Cargo.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@ rustc_macros = { path = "../rustc_macros" }
2222
rustc_serialize = { path = "../rustc_serialize" }
2323
rustc_span = { path = "../rustc_span" }
2424
rustc_target = { path = "../rustc_target" }
25-
smallvec = "1.8.1"
2625
termize = "0.1.1"
2726
tracing = "0.1"
2827
# tidy-alphabetical-end

compiler/rustc_session/src/config.rs

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,28 @@ bitflags::bitflags! {
12961296
}
12971297
}
12981298

1299+
#[derive(Clone, Debug)]
1300+
pub struct Sysroot {
1301+
pub explicit: Option<PathBuf>,
1302+
pub default: PathBuf,
1303+
}
1304+
1305+
impl Sysroot {
1306+
pub fn new(explicit: Option<PathBuf>) -> Sysroot {
1307+
Sysroot { explicit, default: filesearch::default_sysroot() }
1308+
}
1309+
1310+
/// Return explicit sysroot if it was passed with `--sysroot`, or default sysroot otherwise.
1311+
pub fn path(&self) -> &Path {
1312+
self.explicit.as_deref().unwrap_or(&self.default)
1313+
}
1314+
1315+
/// Returns both explicit sysroot if it was passed with `--sysroot` and the default sysroot.
1316+
pub fn all_paths(&self) -> impl Iterator<Item = &Path> {
1317+
self.explicit.as_deref().into_iter().chain(iter::once(&*self.default))
1318+
}
1319+
}
1320+
12991321
pub fn host_tuple() -> &'static str {
13001322
// Get the host triple out of the build environment. This ensures that our
13011323
// idea of the host triple is the same as for the set of libraries we've
@@ -1342,7 +1364,7 @@ impl Default for Options {
13421364
describe_lints: false,
13431365
output_types: OutputTypes(BTreeMap::new()),
13441366
search_paths: vec![],
1345-
sysroot: filesearch::materialize_sysroot(None),
1367+
sysroot: Sysroot::new(None),
13461368
target_triple: TargetTuple::from_tuple(host_tuple()),
13471369
test: false,
13481370
incremental: None,
@@ -2673,7 +2695,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
26732695

26742696
let cg = cg;
26752697

2676-
let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
26772698
let target_triple = parse_target_triple(early_dcx, matches);
26782699
let opt_level = parse_opt_level(early_dcx, matches, &cg);
26792700
// The `-g` and `-C debuginfo` flags specify the same setting, so we want to be able
@@ -2712,10 +2733,10 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
27122733

27132734
let logical_env = parse_logical_env(early_dcx, matches);
27142735

2715-
let sysroot = filesearch::materialize_sysroot(sysroot_opt);
2736+
let sysroot = Sysroot::new(matches.opt_str("sysroot").map(PathBuf::from));
27162737

27172738
let real_source_base_dir = |suffix: &str, confirm: &str| {
2718-
let mut candidate = sysroot.join(suffix);
2739+
let mut candidate = sysroot.path().join(suffix);
27192740
if let Ok(metadata) = candidate.symlink_metadata() {
27202741
// Replace the symlink bootstrap creates, with its destination.
27212742
// We could try to use `fs::canonicalize` instead, but that might
@@ -2742,7 +2763,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
27422763
let mut search_paths = vec![];
27432764
for s in &matches.opt_strs("L") {
27442765
search_paths.push(SearchPath::from_cli_opt(
2745-
&sysroot,
2766+
sysroot.path(),
27462767
&target_triple,
27472768
early_dcx,
27482769
s,

0 commit comments

Comments
 (0)