summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_session/src/config.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_session/src/config.rs')
-rw-r--r--compiler/rustc_session/src/config.rs150
1 files changed, 104 insertions, 46 deletions
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index f97cb3440..f00472f18 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -3,6 +3,7 @@
pub use crate::options::*;
+use crate::errors::FileWriteFail;
use crate::search_paths::SearchPath;
use crate::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
use crate::{lint, HashStableContext};
@@ -11,7 +12,7 @@ use crate::{EarlyErrorHandler, Session};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::stable_hasher::{StableOrd, ToStableHashKey};
use rustc_target::abi::Align;
-use rustc_target::spec::{PanicStrategy, SanitizerSet, SplitDebuginfo};
+use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet, SplitDebuginfo};
use rustc_target::spec::{Target, TargetTriple, TargetWarnings, TARGETS};
use crate::parse::{CrateCheckConfig, CrateConfig};
@@ -31,6 +32,7 @@ use std::collections::btree_map::{
use std::collections::{BTreeMap, BTreeSet};
use std::ffi::OsStr;
use std::fmt;
+use std::fs;
use std::hash::Hash;
use std::iter;
use std::path::{Path, PathBuf};
@@ -277,11 +279,11 @@ impl LinkSelfContained {
// set of all values like `y` or `n` used to be. Therefore, if this flag had previously been
// set in bulk with its historical values, then manually setting a component clears that
// `explicitly_set` state.
- if let Some(component_to_enable) = component.strip_prefix("+") {
+ if let Some(component_to_enable) = component.strip_prefix('+') {
self.explicitly_set = None;
self.components.insert(component_to_enable.parse()?);
Ok(())
- } else if let Some(component_to_disable) = component.strip_prefix("-") {
+ } else if let Some(component_to_disable) = component.strip_prefix('-') {
self.explicitly_set = None;
self.components.remove(component_to_disable.parse()?);
Ok(())
@@ -710,8 +712,14 @@ impl ExternEntry {
}
}
+#[derive(Clone, PartialEq, Debug)]
+pub struct PrintRequest {
+ pub kind: PrintKind,
+ pub out: OutFileName,
+}
+
#[derive(Copy, Clone, PartialEq, Eq, Debug)]
-pub enum PrintRequest {
+pub enum PrintKind {
FileNames,
Sysroot,
TargetLibdir,
@@ -826,9 +834,10 @@ impl OutFileName {
}
pub fn is_tty(&self) -> bool {
+ use std::io::IsTerminal;
match *self {
OutFileName::Real(_) => false,
- OutFileName::Stdout => atty::is(atty::Stream::Stdout),
+ OutFileName::Stdout => std::io::stdout().is_terminal(),
}
}
@@ -855,6 +864,17 @@ impl OutFileName {
OutFileName::Stdout => outputs.temp_path(flavor, codegen_unit_name),
}
}
+
+ pub fn overwrite(&self, content: &str, sess: &Session) {
+ match self {
+ OutFileName::Stdout => print!("{content}"),
+ OutFileName::Real(path) => {
+ if let Err(e) = fs::write(path, content) {
+ sess.emit_fatal(FileWriteFail { path, err: e.to_string() });
+ }
+ }
+ }
+ }
}
#[derive(Clone, Hash, Debug, HashStable_Generic)]
@@ -1173,6 +1193,7 @@ fn default_configuration(sess: &Session) -> CrateConfig {
let os = &sess.target.os;
let env = &sess.target.env;
let abi = &sess.target.abi;
+ let relocation_model = sess.target.relocation_model.desc_symbol();
let vendor = &sess.target.vendor;
let min_atomic_width = sess.target.min_atomic_width();
let max_atomic_width = sess.target.max_atomic_width();
@@ -1198,6 +1219,9 @@ fn default_configuration(sess: &Session) -> CrateConfig {
ret.insert((sym::target_pointer_width, Some(Symbol::intern(&wordsz))));
ret.insert((sym::target_env, Some(Symbol::intern(env))));
ret.insert((sym::target_abi, Some(Symbol::intern(abi))));
+ if sess.is_nightly_build() {
+ ret.insert((sym::relocation_model, Some(relocation_model)));
+ }
ret.insert((sym::target_vendor, Some(Symbol::intern(vendor))));
if sess.target.has_thread_local {
ret.insert((sym::target_thread_local, None));
@@ -1395,6 +1419,8 @@ impl CrateCheckConfig {
.into_iter()
.map(|sanitizer| Symbol::intern(sanitizer.as_str().unwrap()));
+ let relocation_model_values = RelocModel::all();
+
// Unknown possible values:
// - `feature`
// - `target_feature`
@@ -1433,6 +1459,10 @@ impl CrateCheckConfig {
.entry(sym::target_has_atomic_equal_alignment)
.or_insert_with(no_values)
.extend(atomic_values);
+ self.expecteds
+ .entry(sym::relocation_model)
+ .or_insert_with(empty_values)
+ .extend(relocation_model_values);
// Target specific values
{
@@ -1519,9 +1549,8 @@ pub(super) fn build_target_config(
);
let (target, target_warnings) = target_result.unwrap_or_else(|e| {
handler.early_error(format!(
- "Error loading target specification: {}. \
- Run `rustc --print target-list` for a list of built-in targets",
- e
+ "Error loading target specification: {e}. \
+ Run `rustc --print target-list` for a list of built-in targets"
))
});
for warning in target_warnings.warning_messages() {
@@ -1958,8 +1987,7 @@ pub fn parse_crate_edition(handler: &EarlyErrorHandler, matches: &getopts::Match
let is_nightly = nightly_options::match_is_nightly_build(matches);
let msg = if !is_nightly {
format!(
- "the crate requires edition {}, but the latest edition supported by this Rust version is {}",
- edition, LATEST_STABLE_EDITION
+ "the crate requires edition {edition}, but the latest edition supported by this Rust version is {LATEST_STABLE_EDITION}"
)
} else {
format!("edition {edition} is unstable and only available with -Z unstable-options")
@@ -2005,13 +2033,7 @@ fn parse_output_types(
if !unstable_opts.parse_only {
for list in matches.opt_strs("emit") {
for output_type in list.split(',') {
- let (shorthand, path) = match output_type.split_once('=') {
- None => (output_type, None),
- Some((shorthand, "-")) => (shorthand, Some(OutFileName::Stdout)),
- Some((shorthand, path)) => {
- (shorthand, Some(OutFileName::Real(PathBuf::from(path))))
- }
- };
+ let (shorthand, path) = split_out_file_name(output_type);
let output_type = OutputType::from_shorthand(shorthand).unwrap_or_else(|| {
handler.early_error(format!(
"unknown emission type: `{shorthand}` - expected one of: {display}",
@@ -2028,6 +2050,14 @@ fn parse_output_types(
OutputTypes(output_types)
}
+fn split_out_file_name(arg: &str) -> (&str, Option<OutFileName>) {
+ match arg.split_once('=') {
+ None => (arg, None),
+ Some((kind, "-")) => (kind, Some(OutFileName::Stdout)),
+ Some((kind, path)) => (kind, Some(OutFileName::Real(PathBuf::from(path)))),
+ }
+}
+
fn should_override_cgus_and_disable_thinlto(
handler: &EarlyErrorHandler,
output_types: &OutputTypes,
@@ -2091,41 +2121,55 @@ fn collect_print_requests(
) -> Vec<PrintRequest> {
let mut prints = Vec::<PrintRequest>::new();
if cg.target_cpu.as_ref().is_some_and(|s| s == "help") {
- prints.push(PrintRequest::TargetCPUs);
+ prints.push(PrintRequest { kind: PrintKind::TargetCPUs, out: OutFileName::Stdout });
cg.target_cpu = None;
};
if cg.target_feature == "help" {
- prints.push(PrintRequest::TargetFeatures);
+ prints.push(PrintRequest { kind: PrintKind::TargetFeatures, out: OutFileName::Stdout });
cg.target_feature = String::new();
}
- const PRINT_REQUESTS: &[(&str, PrintRequest)] = &[
- ("crate-name", PrintRequest::CrateName),
- ("file-names", PrintRequest::FileNames),
- ("sysroot", PrintRequest::Sysroot),
- ("target-libdir", PrintRequest::TargetLibdir),
- ("cfg", PrintRequest::Cfg),
- ("calling-conventions", PrintRequest::CallingConventions),
- ("target-list", PrintRequest::TargetList),
- ("target-cpus", PrintRequest::TargetCPUs),
- ("target-features", PrintRequest::TargetFeatures),
- ("relocation-models", PrintRequest::RelocationModels),
- ("code-models", PrintRequest::CodeModels),
- ("tls-models", PrintRequest::TlsModels),
- ("native-static-libs", PrintRequest::NativeStaticLibs),
- ("stack-protector-strategies", PrintRequest::StackProtectorStrategies),
- ("target-spec-json", PrintRequest::TargetSpec),
- ("all-target-specs-json", PrintRequest::AllTargetSpecs),
- ("link-args", PrintRequest::LinkArgs),
- ("split-debuginfo", PrintRequest::SplitDebuginfo),
- ("deployment-target", PrintRequest::DeploymentTarget),
+ const PRINT_KINDS: &[(&str, PrintKind)] = &[
+ ("crate-name", PrintKind::CrateName),
+ ("file-names", PrintKind::FileNames),
+ ("sysroot", PrintKind::Sysroot),
+ ("target-libdir", PrintKind::TargetLibdir),
+ ("cfg", PrintKind::Cfg),
+ ("calling-conventions", PrintKind::CallingConventions),
+ ("target-list", PrintKind::TargetList),
+ ("target-cpus", PrintKind::TargetCPUs),
+ ("target-features", PrintKind::TargetFeatures),
+ ("relocation-models", PrintKind::RelocationModels),
+ ("code-models", PrintKind::CodeModels),
+ ("tls-models", PrintKind::TlsModels),
+ ("native-static-libs", PrintKind::NativeStaticLibs),
+ ("stack-protector-strategies", PrintKind::StackProtectorStrategies),
+ ("target-spec-json", PrintKind::TargetSpec),
+ ("all-target-specs-json", PrintKind::AllTargetSpecs),
+ ("link-args", PrintKind::LinkArgs),
+ ("split-debuginfo", PrintKind::SplitDebuginfo),
+ ("deployment-target", PrintKind::DeploymentTarget),
];
+ // We disallow reusing the same path in multiple prints, such as `--print
+ // cfg=output.txt --print link-args=output.txt`, because outputs are printed
+ // by disparate pieces of the compiler, and keeping track of which files
+ // need to be overwritten vs appended to is annoying.
+ let mut printed_paths = FxHashSet::default();
+
prints.extend(matches.opt_strs("print").into_iter().map(|req| {
- match PRINT_REQUESTS.iter().find(|&&(name, _)| name == req) {
- Some((_, PrintRequest::TargetSpec)) => {
+ let (req, out) = split_out_file_name(&req);
+
+ if out.is_some() && !unstable_opts.unstable_options {
+ handler.early_error(
+ "the `-Z unstable-options` flag must also be passed to \
+ enable the path print option",
+ );
+ }
+ let kind = match PRINT_KINDS.iter().find(|&&(name, _)| name == req) {
+ Some((_, PrintKind::TargetSpec)) => {
if unstable_opts.unstable_options {
- PrintRequest::TargetSpec
+ PrintKind::TargetSpec
} else {
handler.early_error(
"the `-Z unstable-options` flag must also be passed to \
@@ -2133,9 +2177,9 @@ fn collect_print_requests(
);
}
}
- Some((_, PrintRequest::AllTargetSpecs)) => {
+ Some((_, PrintKind::AllTargetSpecs)) => {
if unstable_opts.unstable_options {
- PrintRequest::AllTargetSpecs
+ PrintKind::AllTargetSpecs
} else {
handler.early_error(
"the `-Z unstable-options` flag must also be passed to \
@@ -2143,16 +2187,28 @@ fn collect_print_requests(
);
}
}
- Some(&(_, print_request)) => print_request,
+ Some(&(_, print_kind)) => print_kind,
None => {
let prints =
- PRINT_REQUESTS.iter().map(|(name, _)| format!("`{name}`")).collect::<Vec<_>>();
+ PRINT_KINDS.iter().map(|(name, _)| format!("`{name}`")).collect::<Vec<_>>();
let prints = prints.join(", ");
handler.early_error(format!(
"unknown print request `{req}`. Valid print requests are: {prints}"
));
}
+ };
+
+ let out = out.unwrap_or(OutFileName::Stdout);
+ if let OutFileName::Real(path) = &out {
+ if !printed_paths.insert(path.clone()) {
+ handler.early_error(format!(
+ "cannot print multiple outputs to the same path: {}",
+ path.display(),
+ ));
+ }
}
+
+ PrintRequest { kind, out }
}));
prints
@@ -2524,6 +2580,8 @@ pub fn build_session_options(
let error_format = parse_error_format(handler, matches, color, json_rendered);
+ handler.abort_if_error_and_set_error_format(error_format);
+
let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_else(|_| {
handler.early_error("`--diagnostic-width` must be an positive integer");
});