blob: 9cd93817b4ce5ec2665c575ba13115455d90ed78 [file] [log] [blame]
Nick Cameron37ca3672014-05-06 11:38:011//! Contains infrastructure for configuring the compiler, including parsing
Alexander Regueiroc1d29ee2019-09-06 02:57:442//! command-line options.
Nick Cameron37ca3672014-05-06 11:38:013
Nicholas Nethercoteb7d58ee2024-02-20 03:12:504#![allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
5
Nicholas Nethercote84ac80f2024-07-28 22:13:506use std::collections::btree_map::{
7 Iter as BTreeMapIter, Keys as BTreeMapKeysIter, Values as BTreeMapValuesIter,
8};
9use std::collections::{BTreeMap, BTreeSet};
10use std::ffi::OsStr;
11use std::hash::Hash;
12use std::path::{Path, PathBuf};
13use std::str::{self, FromStr};
14use std::sync::LazyLock;
Zalathar001013c2024-11-07 11:47:1515use std::{cmp, fmt, fs, iter};
Victor Ding83fc6002019-12-17 12:22:5516
Urgau5b144972024-04-05 21:01:4017use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
Michael Woerister3a583092022-12-02 14:14:4918use rustc_data_structures::stable_hasher::{StableOrd, ToStableHashKey};
Nicholas Nethercote3521abd2023-11-28 04:29:3919use rustc_errors::emitter::HumanReadableErrorType;
Nicholas Nethercotea09b1d32024-03-05 05:53:2420use rustc_errors::{ColorConfig, DiagArgValue, DiagCtxtFlags, IntoDiagArg};
Mark Rousskova06baa52019-12-22 22:42:0421use rustc_feature::UnstableFeatures;
Nicholas Nethercote4814fd02024-04-28 22:53:4522use rustc_macros::{Decodable, Encodable, HashStable_Generic};
Michael Gouletc682aa12024-09-22 23:05:0423use rustc_span::edition::{DEFAULT_EDITION, EDITION_NAME_LIST, Edition, LATEST_STABLE_EDITION};
Nicholas Nethercotef405ce82023-11-02 03:10:1224use rustc_span::source_map::FilePathMapping;
Kornel88b9edc2024-04-14 12:52:5825use rustc_span::{
Michael Gouletc682aa12024-09-22 23:05:0426 FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm, Symbol, sym,
Kornel88b9edc2024-04-14 12:52:5827};
Nicholas Nethercote84ac80f2024-07-28 22:13:5028use rustc_target::spec::{
Noratrieba26450c2024-10-17 17:02:3229 FramePointer, LinkSelfContainedComponents, LinkerFeatures, SplitDebuginfo, Target, TargetTuple,
Alexander Regueiroc1d29ee2019-09-06 02:57:4430};
Nicholas Nethercote63419352024-04-29 06:24:0631use tracing::debug;
Nick Cameron37ca3672014-05-06 11:38:0132
Zalathar478db482024-11-11 10:39:5233pub use crate::config::cfg::{Cfg, CheckCfg, ExpectedValues};
Zalathar78edefe2024-11-11 10:42:4234use crate::config::native_libs::parse_native_libs;
Nicholas Nethercote84ac80f2024-07-28 22:13:5035use crate::errors::FileWriteFail;
36pub use crate::options::*;
37use crate::search_paths::SearchPath;
Zalathar478db482024-11-11 10:39:5238use crate::utils::CanonicalizedPath;
Michael Gouletc682aa12024-09-22 23:05:0439use crate::{EarlyDiagCtxt, HashStableContext, Session, filesearch, lint};
Nicholas Nethercote84ac80f2024-07-28 22:13:5040
Urgau5b144972024-04-05 21:01:4041mod cfg;
Zalathar478db482024-11-11 10:39:5242mod native_libs;
Martin Nordholtsddee45e2022-07-05 17:56:2243pub mod sigpipe;
44
Josh Triplette35b7bb2021-10-21 11:19:4645/// The different settings that the `-C strip` flag can have.
YIa6c2f732020-05-03 04:36:1246#[derive(Clone, Copy, PartialEq, Hash, Debug)]
47pub enum Strip {
48 /// Do not strip at all.
49 None,
50
51 /// Strip debuginfo.
52 Debuginfo,
53
54 /// Strip all symbols.
55 Symbols,
56}
57
Andrew Paverd31c7aae2020-07-14 14:27:4258/// The different settings that the `-C control-flow-guard` flag can have.
Andrew Paverdc0744e12020-01-13 13:25:3959#[derive(Clone, Copy, PartialEq, Hash, Debug)]
60pub enum CFGuard {
61 /// Do not emit Control Flow Guard metadata or checks.
62 Disabled,
63
64 /// Emit Control Flow Guard metadata but no checks.
65 NoChecks,
66
67 /// Emit Control Flow Guard metadata and checks.
68 Checks,
69}
70
Andrew Brown8d6c9732022-01-28 17:48:5971/// The different settings that the `-Z cf-protection` flag can have.
72#[derive(Clone, Copy, PartialEq, Hash, Debug)]
73pub enum CFProtection {
74 /// Do not enable control-flow protection
75 None,
76
77 /// Emit control-flow protection for branches (enables indirect branch tracking).
78 Branch,
79
80 /// Emit control-flow protection for returns.
81 Return,
82
83 /// Emit control-flow protection for both branches and returns.
84 Full,
85}
86
Michael Woeristerc0be6192022-04-19 08:43:0987#[derive(Clone, Copy, Debug, PartialEq, Hash, HashStable_Generic)]
Nick Cameron37ca3672014-05-06 11:38:0188pub enum OptLevel {
Santiago Pastorino52a47d42018-03-06 05:29:0389 No, // -O0
90 Less, // -O1
91 Default, // -O2
Brandon Edensb1337d32016-03-27 19:42:4792 Aggressive, // -O3
Santiago Pastorino52a47d42018-03-06 05:29:0393 Size, // -Os
94 SizeMin, // -Oz
Nick Cameron37ca3672014-05-06 11:38:0195}
96
Michael Woerister24093a62018-09-04 15:57:1797/// This is what the `LtoCli` values get mapped to after resolving defaults and
98/// and taking other command line options into account.
Edd Barrett8cc918a2021-04-20 09:19:2599///
100/// Note that linker plugin-based LTO is a different mechanism entirely.
Nicholas Nethercoteac6daed2019-10-20 04:54:53101#[derive(Clone, PartialEq)]
Alex Crichton8bde2ac2018-01-16 23:02:31102pub enum Lto {
Edd Barrett8cc918a2021-04-20 09:19:25103 /// Don't do any LTO whatsoever.
Alex Crichton8bde2ac2018-01-16 23:02:31104 No,
105
Edd Barrett8cc918a2021-04-20 09:19:25106 /// Do a full-crate-graph (inter-crate) LTO with ThinLTO.
Alex Crichton8bde2ac2018-01-16 23:02:31107 Thin,
108
Edd Barrett8cc918a2021-04-20 09:19:25109 /// Do a local ThinLTO (intra-crate, over the CodeGen Units of the local crate only). This is
110 /// only relevant if multiple CGUs are used.
Alex Crichton8bde2ac2018-01-16 23:02:31111 ThinLocal,
112
Edd Barrett8cc918a2021-04-20 09:19:25113 /// Do a full-crate-graph (inter-crate) LTO with "fat" LTO.
Alex Crichton8bde2ac2018-01-16 23:02:31114 Fat,
115}
116
Michael Woerister24093a62018-09-04 15:57:17117/// The different settings that the `-C lto` flag can have.
118#[derive(Clone, Copy, PartialEq, Hash, Debug)]
119pub enum LtoCli {
120 /// `-C lto=no`
121 No,
122 /// `-C lto=yes`
123 Yes,
124 /// `-C lto`
125 NoParam,
126 /// `-C lto=thin`
127 Thin,
128 /// `-C lto=fat`
129 Fat,
130 /// No `-C lto` flag passed
131 Unspecified,
132}
133
Josh Triplett34106f82021-10-21 14:04:22134/// The different settings that the `-C instrument-coverage` flag can have.
Rich Kadelbcf75552021-03-15 23:32:45135#[derive(Clone, Copy, PartialEq, Hash, Debug)]
136pub enum InstrumentCoverage {
Zalathar9f287dd2023-10-25 03:57:25137 /// `-C instrument-coverage=no` (or `off`, `false` etc.)
138 No,
139 /// `-C instrument-coverage` or `-C instrument-coverage=yes`
140 Yes,
Rich Kadelbcf75552021-03-15 23:32:45141}
142
Zalatharaced4dc2024-12-19 10:53:10143/// Individual flag values controlled by `-Zcoverage-options`.
Matthias Krüger0437a0c2024-03-17 12:37:54144#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
Zalathar3407fcc2024-03-08 07:07:04145pub struct CoverageOptions {
Zalatharf9263372024-04-29 06:19:55146 pub level: CoverageLevel,
Zalatharabc2c702024-06-17 10:09:45147
Zalatharaced4dc2024-12-19 10:53:10148 /// `-Zcoverage-options=no-mir-spans`: Don't extract block coverage spans
Zalatharabc2c702024-06-17 10:09:45149 /// from MIR statements/terminators, making it easier to inspect/debug
150 /// branch and MC/DC coverage mappings.
151 ///
152 /// For internal debugging only. If other code changes would make it hard
153 /// to keep supporting this flag, remove it.
154 pub no_mir_spans: bool,
Zalatharaced4dc2024-12-19 10:53:10155
156 /// `-Zcoverage-options=discard-all-spans-in-codegen`: During codgen,
157 /// discard all coverage spans as though they were invalid. Needed by
158 /// regression tests for #133606, because we don't have an easy way to
159 /// reproduce it from actual source code.
160 pub discard_all_spans_in_codegen: bool,
Zalatharf9263372024-04-29 06:19:55161}
162
163/// Controls whether branch coverage or MC/DC coverage is enabled.
Esteban Küber1f82b452024-12-11 01:37:17164#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Default)]
Zalatharf9263372024-04-29 06:19:55165pub enum CoverageLevel {
166 /// Instrument for coverage at the MIR block level.
Esteban Küber1f82b452024-12-11 01:37:17167 #[default]
Zalatharf9263372024-04-29 06:19:55168 Block,
169 /// Also instrument branch points (includes block coverage).
170 Branch,
Dorian Péronfa563c12024-04-26 13:01:06171 /// Same as branch coverage, but also adds branch instrumentation for
172 /// certain boolean expressions that are not directly used for branching.
173 ///
174 /// For example, in the following code, `b` does not directly participate
175 /// in a branch, but condition coverage will instrument it as its own
176 /// artificial branch:
177 /// ```
178 /// # let (a, b) = (false, true);
179 /// let x = a && b;
180 /// // ^ last operand
181 /// ```
182 ///
183 /// This level is mainly intended to be a stepping-stone towards full MC/DC
184 /// instrumentation, so it might be removed in the future when MC/DC is
185 /// sufficiently complete, or if it is making MC/DC changes difficult.
186 Condition,
187 /// Instrument for MC/DC. Mostly a superset of condition coverage, but might
Zalatharf9263372024-04-29 06:19:55188 /// differ in some corner cases.
189 Mcdc,
190}
191
Oleksii Lozovskyi0e60df92022-09-24 11:02:44192/// Settings for `-Z instrument-xray` flag.
193#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
194pub struct InstrumentXRay {
195 /// `-Z instrument-xray=always`, force instrumentation
196 pub always: bool,
197 /// `-Z instrument-xray=never`, disable instrumentation
198 pub never: bool,
199 /// `-Z instrument-xray=ignore-loops`, ignore presence of loops,
200 /// instrument functions based only on instruction count
201 pub ignore_loops: bool,
202 /// `-Z instrument-xray=instruction-threshold=N`, explicitly set instruction threshold
203 /// for instrumentation, or `None` to use compiler's default
204 pub instruction_threshold: Option<usize>,
205 /// `-Z instrument-xray=skip-entry`, do not instrument function entry
206 pub skip_entry: bool,
207 /// `-Z instrument-xray=skip-exit`, do not instrument function exit
208 pub skip_exit: bool,
209}
210
Joshua Nelsonfb7018b2021-04-16 03:06:32211#[derive(Clone, PartialEq, Hash, Debug)]
Michael Woerister04f425d2019-02-01 14:15:43212pub enum LinkerPluginLto {
Michael Woeristera9810892018-04-25 13:45:04213 LinkerPlugin(PathBuf),
Michael Woerister65ff4142018-07-03 14:33:11214 LinkerPluginAuto,
Mark Rousskova06baa52019-12-22 22:42:04215 Disabled,
Michael Woeristera9810892018-04-25 13:45:04216}
217
Rémy Rakic5bc88702023-06-21 17:54:27218impl LinkerPluginLto {
219 pub fn enabled(&self) -> bool {
220 match *self {
221 LinkerPluginLto::LinkerPlugin(_) | LinkerPluginLto::LinkerPluginAuto => true,
222 LinkerPluginLto::Disabled => false,
223 }
224 }
225}
226
Rémy Rakic5d91c1c2023-06-21 21:45:13227/// The different values `-C link-self-contained` can take: a list of individually enabled or
228/// disabled components used during linking, coming from the rustc distribution, instead of being
229/// found somewhere on the host system.
230///
231/// They can be set in bulk via `-C link-self-contained=yes|y|on` or `-C
232/// link-self-contained=no|n|off`, and those boolean values are the historical defaults.
233///
234/// But each component is fine-grained, and can be unstably targeted, to use:
235/// - some CRT objects
236/// - the libc static library
237/// - libgcc/libunwind libraries
238/// - a linker we distribute
239/// - some sanitizer runtime libraries
240/// - all other MinGW libraries and Windows import libs
241///
242#[derive(Default, Clone, PartialEq, Debug)]
243pub struct LinkSelfContained {
244 /// Whether the user explicitly set `-C link-self-contained` on or off, the historical values.
245 /// Used for compatibility with the existing opt-in and target inference.
246 pub explicitly_set: Option<bool>,
247
Rémy Rakic5b9aa262023-09-20 20:25:17248 /// The components that are enabled on the CLI, using the `+component` syntax or one of the
Alexander Cyon00de0062024-09-02 05:50:22249 /// `true` shortcuts.
Rémy Rakic5b9aa262023-09-20 20:25:17250 enabled_components: LinkSelfContainedComponents,
251
252 /// The components that are disabled on the CLI, using the `-component` syntax or one of the
253 /// `false` shortcuts.
254 disabled_components: LinkSelfContainedComponents,
Rémy Rakic5d91c1c2023-06-21 21:45:13255}
256
Rémy Rakic0fb80712023-06-21 21:46:36257impl LinkSelfContained {
258 /// Incorporates an enabled or disabled component as specified on the CLI, if possible.
259 /// For example: `+linker`, and `-crto`.
Rémy Rakic2ce46f82023-09-20 20:09:06260 pub(crate) fn handle_cli_component(&mut self, component: &str) -> Option<()> {
Rémy Rakic0fb80712023-06-21 21:46:36261 // Note that for example `-Cself-contained=y -Cself-contained=-linker` is not an explicit
262 // set of all values like `y` or `n` used to be. Therefore, if this flag had previously been
263 // set in bulk with its historical values, then manually setting a component clears that
264 // `explicitly_set` state.
Matthias Krüger7a770892023-07-23 08:12:40265 if let Some(component_to_enable) = component.strip_prefix('+') {
Rémy Rakic0fb80712023-06-21 21:46:36266 self.explicitly_set = None;
Rémy Rakic5b9aa262023-09-20 20:25:17267 self.enabled_components
268 .insert(LinkSelfContainedComponents::from_str(component_to_enable)?);
Rémy Rakic2ce46f82023-09-20 20:09:06269 Some(())
Matthias Krüger7a770892023-07-23 08:12:40270 } else if let Some(component_to_disable) = component.strip_prefix('-') {
Rémy Rakic0fb80712023-06-21 21:46:36271 self.explicitly_set = None;
Rémy Rakic5b9aa262023-09-20 20:25:17272 self.disabled_components
273 .insert(LinkSelfContainedComponents::from_str(component_to_disable)?);
Rémy Rakic2ce46f82023-09-20 20:09:06274 Some(())
Rémy Rakic0fb80712023-06-21 21:46:36275 } else {
Rémy Rakic2ce46f82023-09-20 20:09:06276 None
Rémy Rakic0fb80712023-06-21 21:46:36277 }
278 }
279
280 /// Turns all components on or off and records that this was done explicitly for compatibility
281 /// purposes.
282 pub(crate) fn set_all_explicitly(&mut self, enabled: bool) {
283 self.explicitly_set = Some(enabled);
Rémy Rakic5b9aa262023-09-20 20:25:17284
285 if enabled {
286 self.enabled_components = LinkSelfContainedComponents::all();
287 self.disabled_components = LinkSelfContainedComponents::empty();
Rémy Rakic0fb80712023-06-21 21:46:36288 } else {
Rémy Rakic5b9aa262023-09-20 20:25:17289 self.enabled_components = LinkSelfContainedComponents::empty();
290 self.disabled_components = LinkSelfContainedComponents::all();
291 }
Rémy Rakic0fb80712023-06-21 21:46:36292 }
293
294 /// Helper creating a fully enabled `LinkSelfContained` instance. Used in tests.
295 pub fn on() -> Self {
296 let mut on = LinkSelfContained::default();
297 on.set_all_explicitly(true);
298 on
299 }
Rémy Rakic1da271b2023-06-21 15:49:10300
Rémy Rakic38dca732023-06-21 21:49:41301 /// To help checking CLI usage while some of the values are unstable: returns whether one of the
302 /// components was set individually. This would also require the `-Zunstable-options` flag, to
303 /// be allowed.
304 fn are_unstable_variants_set(&self) -> bool {
Rémy Rakic5b9aa262023-09-20 20:25:17305 let any_component_set =
306 !self.enabled_components.is_empty() || !self.disabled_components.is_empty();
Rémy Rakic38dca732023-06-21 21:49:41307 self.explicitly_set.is_none() && any_component_set
308 }
309
Rémy Rakic5b9aa262023-09-20 20:25:17310 /// Returns whether the self-contained linker component was enabled on the CLI, using the
Alexander Cyon00de0062024-09-02 05:50:22311 /// `-C link-self-contained=+linker` syntax, or one of the `true` shortcuts.
Rémy Rakic5b9aa262023-09-20 20:25:17312 pub fn is_linker_enabled(&self) -> bool {
313 self.enabled_components.contains(LinkSelfContainedComponents::LINKER)
314 }
315
316 /// Returns whether the self-contained linker component was disabled on the CLI, using the
Alexander Cyon00de0062024-09-02 05:50:22317 /// `-C link-self-contained=-linker` syntax, or one of the `false` shortcuts.
Rémy Rakic5b9aa262023-09-20 20:25:17318 pub fn is_linker_disabled(&self) -> bool {
319 self.disabled_components.contains(LinkSelfContainedComponents::LINKER)
Rémy Rakic1da271b2023-06-21 15:49:10320 }
Rémy Rakic13948742023-09-21 13:27:45321
322 /// Returns CLI inconsistencies to emit errors: individual components were both enabled and
323 /// disabled.
324 fn check_consistency(&self) -> Option<LinkSelfContainedComponents> {
325 if self.explicitly_set.is_some() {
326 None
327 } else {
328 let common = self.enabled_components.intersection(self.disabled_components);
329 if common.is_empty() { None } else { Some(common) }
330 }
331 }
Rémy Rakic0fb80712023-06-21 21:46:36332}
333
Rémy Rakic2398d8c2024-04-08 21:40:44334/// The different values that `-Z linker-features` can take on the CLI: a list of individually
335/// enabled or disabled features used during linking.
336///
337/// There is no need to enable or disable them in bulk. Each feature is fine-grained, and can be
338/// used to turn `LinkerFeatures` on or off, without needing to change the linker flavor:
339/// - using the system lld, or the self-contained `rust-lld` linker
340/// - using a C/C++ compiler to drive the linker (not yet exposed on the CLI)
341/// - etc.
342#[derive(Default, Copy, Clone, PartialEq, Debug)]
343pub struct LinkerFeaturesCli {
344 /// The linker features that are enabled on the CLI, using the `+feature` syntax.
345 pub enabled: LinkerFeatures,
346
347 /// The linker features that are disabled on the CLI, using the `-feature` syntax.
348 pub disabled: LinkerFeatures,
349}
350
351impl LinkerFeaturesCli {
352 /// Accumulates an enabled or disabled feature as specified on the CLI, if possible.
353 /// For example: `+lld`, and `-lld`.
354 pub(crate) fn handle_cli_feature(&mut self, feature: &str) -> Option<()> {
355 // Duplicate flags are reduced as we go, the last occurrence wins:
356 // `+feature,-feature,+feature` only enables the feature, and does not record it as both
357 // enabled and disabled on the CLI.
Alexander Cyon00de0062024-09-02 05:50:22358 // We also only expose `+/-lld` at the moment, as it's currently the only implemented linker
Rémy Rakic2398d8c2024-04-08 21:40:44359 // feature and toggling `LinkerFeatures::CC` would be a noop.
360 match feature {
361 "+lld" => {
362 self.enabled.insert(LinkerFeatures::LLD);
363 self.disabled.remove(LinkerFeatures::LLD);
364 Some(())
365 }
366 "-lld" => {
367 self.disabled.insert(LinkerFeatures::LLD);
368 self.enabled.remove(LinkerFeatures::LLD);
369 Some(())
370 }
371 _ => None,
372 }
373 }
374}
375
pierwill1642fdf2021-10-31 22:05:48376/// Used with `-Z assert-incr-state`.
377#[derive(Clone, Copy, PartialEq, Hash, Debug)]
378pub enum IncrementalStateAssertion {
379 /// Found and loaded an existing session directory.
380 ///
381 /// Note that this says nothing about whether any particular query
382 /// will be found to be red or green.
383 Loaded,
384 /// Did not load an existing session directory.
385 NotLoaded,
386}
387
Hudson Ayersa9a13932021-10-14 00:01:31388/// The different settings that can be enabled via the `-Z location-detail` flag.
Maybe Waffle09a87912023-04-13 18:04:30389#[derive(Copy, Clone, PartialEq, Hash, Debug)]
Hudson Ayersa9a13932021-10-14 00:01:31390pub struct LocationDetail {
391 pub file: bool,
392 pub line: bool,
393 pub column: bool,
394}
395
396impl LocationDetail {
Nicholas Nethercotede388882024-03-19 02:31:28397 pub(crate) fn all() -> Self {
Hudson Ayersa9a13932021-10-14 00:01:31398 Self { file: true, line: true, column: true }
399 }
400}
401
Kornel88b9edc2024-04-14 12:52:58402/// Values for the `-Z fmt-debug` flag.
403#[derive(Copy, Clone, PartialEq, Hash, Debug)]
404pub enum FmtDebug {
405 /// Derive fully-featured implementation
406 Full,
407 /// Print only type name, without fields
408 Shallow,
409 /// `#[derive(Debug)]` and `{:?}` are no-ops
410 None,
411}
412
413impl FmtDebug {
414 pub(crate) fn all() -> [Symbol; 3] {
415 [sym::full, sym::none, sym::shallow]
416 }
417}
418
Joshua Nelsonfb7018b2021-04-16 03:06:32419#[derive(Clone, PartialEq, Hash, Debug)]
Michael Woerister64ee32e2019-05-28 14:13:59420pub enum SwitchWithOptPath {
Michael Woerister7b1df422019-04-10 11:46:37421 Enabled(Option<PathBuf>),
422 Disabled,
423}
424
Michael Woerister64ee32e2019-05-28 14:13:59425impl SwitchWithOptPath {
Michael Woerister7b1df422019-04-10 11:46:37426 pub fn enabled(&self) -> bool {
427 match *self {
Michael Woerister64ee32e2019-05-28 14:13:59428 SwitchWithOptPath::Enabled(_) => true,
429 SwitchWithOptPath::Disabled => false,
Michael Woerister7b1df422019-04-10 11:46:37430 }
431 }
432}
433
Michael Woeristerc0be6192022-04-19 08:43:09434#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, HashStable_Generic)]
Matthew Jaspercbcef3e2020-06-11 14:49:57435#[derive(Encodable, Decodable)]
Eduard-Mihai Burtescu20929632019-01-29 05:24:32436pub enum SymbolManglingVersion {
437 Legacy,
438 V0,
h14677928226e53e662023-12-05 04:42:57439 Hashed,
Eduard-Mihai Burtescu20929632019-01-29 05:24:32440}
441
J. Ryan Stinnett8b18f412020-11-28 15:07:51442#[derive(Clone, Copy, Debug, PartialEq, Hash)]
Mark Rousskov2bc71972018-07-26 17:41:10443pub enum DebugInfo {
444 None,
Julia Tatz0504a332021-04-06 20:00:35445 LineDirectivesOnly,
446 LineTablesOnly,
Mark Rousskov2bc71972018-07-26 17:41:10447 Limited,
448 Full,
Nick Cameron37ca3672014-05-06 11:38:01449}
450
Augie Fackleraf9e5502023-07-12 21:07:34451#[derive(Clone, Copy, Debug, PartialEq, Hash)]
452pub enum DebugInfoCompression {
453 None,
454 Zlib,
455 Zstd,
456}
457
458impl ToString for DebugInfoCompression {
459 fn to_string(&self) -> String {
460 match self {
461 DebugInfoCompression::None => "none",
462 DebugInfoCompression::Zlib => "zlib",
463 DebugInfoCompression::Zstd => "zstd",
464 }
465 .to_owned()
466 }
467}
468
Scott McMurraya7fc76a2024-12-05 08:47:36469#[derive(Clone, Copy, Debug, PartialEq, Hash)]
470pub enum MirStripDebugInfo {
471 None,
472 LocalsInTinyFunctions,
473 AllLocals,
474}
475
David Wood08ed3382021-10-08 16:10:17476/// Split debug-information is enabled by `-C split-debuginfo`, this enum is only used if split
477/// debug-information is enabled (in either `Packed` or `Unpacked` modes), and the platform
478/// uses DWARF for debug-information.
479///
480/// Some debug-information requires link-time relocation and some does not. LLVM can partition
481/// the debuginfo into sections depending on whether or not it requires link-time relocation. Split
482/// DWARF provides a mechanism which allows the linker to skip the sections which don't require
483/// link-time relocation - either by putting those sections in DWARF object files, or by keeping
484/// them in the object file in such a way that the linker will skip them.
485#[derive(Clone, Copy, Debug, PartialEq, Hash)]
486pub enum SplitDwarfKind {
487 /// Sections which do not require relocation are written into object file but ignored by the
488 /// linker.
489 Single,
490 /// Sections which do not require relocation are written into a DWARF object (`.dwo`) file
491 /// which is ignored by the linker.
492 Split,
493}
494
495impl FromStr for SplitDwarfKind {
496 type Err = ();
497
498 fn from_str(s: &str) -> Result<Self, ()> {
499 Ok(match s {
500 "single" => SplitDwarfKind::Single,
501 "split" => SplitDwarfKind::Split,
502 _ => return Err(()),
503 })
504 }
505}
506
Michael Woeristerc0be6192022-04-19 08:43:09507#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, HashStable_Generic)]
Matthew Jaspercbcef3e2020-06-11 14:49:57508#[derive(Encodable, Decodable)]
Niko Matsakisdc6e4142014-11-16 01:30:33509pub enum OutputType {
Alex Crichton8c963c02015-09-30 17:08:37510 Bitcode,
Augie Fackleraa918712024-01-19 19:42:43511 ThinLinkBitcode,
Alex Crichton8c963c02015-09-30 17:08:37512 Assembly,
513 LlvmAssembly,
Jake Goulding9218f972017-02-16 21:59:09514 Mir,
Nick Cameron7720cf02016-12-23 06:39:20515 Metadata,
Alex Crichton8c963c02015-09-30 17:08:37516 Object,
517 Exe,
518 DepInfo,
Niko Matsakisdc6e4142014-11-16 01:30:33519}
520
Alan Egerton114dd202024-06-12 12:01:22521impl StableOrd for OutputType {
Andrew Xie54d7b322023-06-08 04:38:50522 const CAN_USE_UNSTABLE_SORT: bool = true;
Alan Egerton0e73e702024-06-22 06:11:42523
524 // Trivial C-Style enums have a stable sort order across compilation sessions.
525 const THIS_IMPLEMENTATION_HAS_BEEN_TRIPLE_CHECKED: () = ();
Andrew Xie54d7b322023-06-08 04:38:50526}
Michael Woerister3a583092022-12-02 14:14:49527
Michael Woeristerc0be6192022-04-19 08:43:09528impl<HCX: HashStableContext> ToStableHashKey<HCX> for OutputType {
529 type KeyType = Self;
530
531 fn to_stable_hash_key(&self, _: &HCX) -> Self::KeyType {
532 *self
533 }
534}
Michael Woerister74d6b852017-09-18 10:14:52535
Felix S. Klock IIf90c21a2015-12-04 18:35:16536impl OutputType {
537 fn is_compatible_with_codegen_units_and_single_output_file(&self) -> bool {
538 match *self {
Alex Crichton955f2832019-04-25 16:06:38539 OutputType::Exe | OutputType::DepInfo | OutputType::Metadata => true,
Santiago Pastorino52a47d42018-03-06 05:29:03540 OutputType::Bitcode
Augie Fackleraa918712024-01-19 19:42:43541 | OutputType::ThinLinkBitcode
Santiago Pastorino52a47d42018-03-06 05:29:03542 | OutputType::Assembly
543 | OutputType::LlvmAssembly
544 | OutputType::Mir
Alex Crichton955f2832019-04-25 16:06:38545 | OutputType::Object => false,
Felix S. Klock IIf90c21a2015-12-04 18:35:16546 }
547 }
548
Jing Peng9b1a1e12023-02-26 20:27:27549 pub fn shorthand(&self) -> &'static str {
Felix S. Klock IIf90c21a2015-12-04 18:35:16550 match *self {
551 OutputType::Bitcode => "llvm-bc",
Augie Fackleraa918712024-01-19 19:42:43552 OutputType::ThinLinkBitcode => "thin-link-bitcode",
Felix S. Klock IIf90c21a2015-12-04 18:35:16553 OutputType::Assembly => "asm",
554 OutputType::LlvmAssembly => "llvm-ir",
Jake Goulding9218f972017-02-16 21:59:09555 OutputType::Mir => "mir",
Felix S. Klock IIf90c21a2015-12-04 18:35:16556 OutputType::Object => "obj",
Nick Cameron7720cf02016-12-23 06:39:20557 OutputType::Metadata => "metadata",
Felix S. Klock IIf90c21a2015-12-04 18:35:16558 OutputType::Exe => "link",
559 OutputType::DepInfo => "dep-info",
560 }
561 }
Niko Matsakis2f9fff212016-07-25 14:51:14562
Corey Farwellc3ea3582017-11-05 14:20:59563 fn from_shorthand(shorthand: &str) -> Option<Self> {
564 Some(match shorthand {
Santiago Pastorino52a47d42018-03-06 05:29:03565 "asm" => OutputType::Assembly,
566 "llvm-ir" => OutputType::LlvmAssembly,
567 "mir" => OutputType::Mir,
568 "llvm-bc" => OutputType::Bitcode,
Augie Fackleraa918712024-01-19 19:42:43569 "thin-link-bitcode" => OutputType::ThinLinkBitcode,
Santiago Pastorino52a47d42018-03-06 05:29:03570 "obj" => OutputType::Object,
571 "metadata" => OutputType::Metadata,
572 "link" => OutputType::Exe,
573 "dep-info" => OutputType::DepInfo,
Corey Farwellc3ea3582017-11-05 14:20:59574 _ => return None,
575 })
576 }
577
578 fn shorthands_display() -> String {
579 format!(
Augie Fackleraa918712024-01-19 19:42:43580 "`{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`",
Corey Farwellc3ea3582017-11-05 14:20:59581 OutputType::Bitcode.shorthand(),
Augie Fackleraa918712024-01-19 19:42:43582 OutputType::ThinLinkBitcode.shorthand(),
Corey Farwellc3ea3582017-11-05 14:20:59583 OutputType::Assembly.shorthand(),
584 OutputType::LlvmAssembly.shorthand(),
585 OutputType::Mir.shorthand(),
586 OutputType::Object.shorthand(),
587 OutputType::Metadata.shorthand(),
588 OutputType::Exe.shorthand(),
589 OutputType::DepInfo.shorthand(),
590 )
591 }
592
Niko Matsakis2f9fff212016-07-25 14:51:14593 pub fn extension(&self) -> &'static str {
594 match *self {
595 OutputType::Bitcode => "bc",
Augie Fackleraa918712024-01-19 19:42:43596 OutputType::ThinLinkBitcode => "indexing.o",
Niko Matsakis2f9fff212016-07-25 14:51:14597 OutputType::Assembly => "s",
598 OutputType::LlvmAssembly => "ll",
Jake Goulding9218f972017-02-16 21:59:09599 OutputType::Mir => "mir",
Niko Matsakis2f9fff212016-07-25 14:51:14600 OutputType::Object => "o",
Nick Cameron7720cf02016-12-23 06:39:20601 OutputType::Metadata => "rmeta",
Niko Matsakis2f9fff212016-07-25 14:51:14602 OutputType::DepInfo => "d",
603 OutputType::Exe => "",
604 }
605 }
Jing Peng9b1a1e12023-02-26 20:27:27606
607 pub fn is_text_output(&self) -> bool {
608 match *self {
609 OutputType::Assembly
610 | OutputType::LlvmAssembly
611 | OutputType::Mir
612 | OutputType::DepInfo => true,
Augie Fackleraa918712024-01-19 19:42:43613 OutputType::Bitcode
614 | OutputType::ThinLinkBitcode
615 | OutputType::Object
616 | OutputType::Metadata
617 | OutputType::Exe => false,
Jing Peng9b1a1e12023-02-26 20:27:27618 }
619 }
Felix S. Klock IIf90c21a2015-12-04 18:35:16620}
621
Philipp Hansch33137ff2019-06-10 08:59:03622/// The type of diagnostics output to generate.
Nick Cameronb286a2f2016-10-25 22:14:02623#[derive(Clone, Copy, Debug, PartialEq, Eq)]
624pub enum ErrorOutputType {
Philipp Hansche3516a12019-06-09 10:04:40625 /// Output meant for the consumption of humans.
Esteban Küberae696f82024-08-08 01:46:16626 HumanReadable(HumanReadableErrorType, ColorConfig),
Philipp Hansche3516a12019-06-09 10:04:40627 /// Output that's consumed by other tools such as `rustfix` or the `RLS`.
Oliver Scherer96404ee2019-03-12 12:06:43628 Json {
Philipp Hansch33137ff2019-06-10 08:59:03629 /// Render the JSON in a human readable way (with indents and newlines).
Oliver Scherer96404ee2019-03-12 12:06:43630 pretty: bool,
Philipp Hansche3516a12019-06-09 10:04:40631 /// The JSON output includes a `rendered` field that includes the rendered
632 /// human output.
Oliver Scherer39b21372019-03-25 10:16:58633 json_rendered: HumanReadableErrorType,
Esteban Küberae696f82024-08-08 01:46:16634 color_config: ColorConfig,
Oliver Scherer96404ee2019-03-12 12:06:43635 },
Nick Cameronb286a2f2016-10-25 22:14:02636}
637
638impl Default for ErrorOutputType {
Alexander Regueiroc1d29ee2019-09-06 02:57:44639 fn default() -> Self {
Esteban Küberae696f82024-08-08 01:46:16640 Self::HumanReadable(HumanReadableErrorType::Default, ColorConfig::Auto)
Nick Cameronb286a2f2016-10-25 22:14:02641 }
642}
643
bohanf34678c2023-05-11 18:09:46644#[derive(Clone, Hash, Debug)]
Vadim Petrochenkovda4ce6b2023-02-06 17:57:45645pub enum ResolveDocLinks {
646 /// Do not resolve doc links.
647 None,
648 /// Resolve doc links on exported items only for crate types that have metadata.
649 ExportedMetadata,
650 /// Resolve doc links on exported items.
651 Exported,
652 /// Resolve doc links on all items.
653 All,
654}
655
Alexander Regueiroc1d29ee2019-09-06 02:57:44656/// Use tree-based collections to cheaply get a deterministic `Hash` implementation.
657/// *Do not* switch `BTreeMap` out for an unsorted container type! That would break
Jeremy Fitzhardingea26d99f2021-06-05 22:43:12658/// dependency tracking for command-line arguments. Also only hash keys, since tracking
659/// should only depend on the output types, not the paths they're written to.
bjorn398a6eaa2023-11-04 15:49:57660#[derive(Clone, Debug, Hash, HashStable_Generic, Encodable, Decodable)]
Jing Peng9b1a1e12023-02-26 20:27:27661pub struct OutputTypes(BTreeMap<OutputType, Option<OutFileName>>);
Nick Cameron37ca3672014-05-06 11:38:01662
Michael Woerister32414312016-08-02 20:53:58663impl OutputTypes {
Jing Peng9b1a1e12023-02-26 20:27:27664 pub fn new(entries: &[(OutputType, Option<OutFileName>)]) -> OutputTypes {
Mark Rousskova06baa52019-12-22 22:42:04665 OutputTypes(BTreeMap::from_iter(entries.iter().map(|&(k, ref v)| (k, v.clone()))))
Michael Woerister32414312016-08-02 20:53:58666 }
Niko Matsakisd09fd1a2016-01-29 20:07:04667
Nicholas Nethercotede388882024-03-19 02:31:28668 pub(crate) fn get(&self, key: &OutputType) -> Option<&Option<OutFileName>> {
Michael Woerister32414312016-08-02 20:53:58669 self.0.get(key)
670 }
Niko Matsakisd09fd1a2016-01-29 20:07:04671
Michael Woerister32414312016-08-02 20:53:58672 pub fn contains_key(&self, key: &OutputType) -> bool {
673 self.0.contains_key(key)
674 }
675
Michael Baikovbf12aa42024-03-21 20:13:46676 /// Returns `true` if user specified a name and not just produced type
677 pub fn contains_explicit_name(&self, key: &OutputType) -> bool {
Yotam Ofek264fa0f2025-01-19 19:15:00678 self.0.get(key).is_some_and(|f| f.is_some())
Michael Baikovbf12aa42024-03-21 20:13:46679 }
680
Jing Peng9b1a1e12023-02-26 20:27:27681 pub fn iter(&self) -> BTreeMapIter<'_, OutputType, Option<OutFileName>> {
682 self.0.iter()
683 }
684
685 pub fn keys(&self) -> BTreeMapKeysIter<'_, OutputType, Option<OutFileName>> {
Michael Woerister32414312016-08-02 20:53:58686 self.0.keys()
687 }
688
Jing Peng9b1a1e12023-02-26 20:27:27689 pub fn values(&self) -> BTreeMapValuesIter<'_, OutputType, Option<OutFileName>> {
Michael Woerister32414312016-08-02 20:53:58690 self.0.values()
691 }
Nick Cameronb059a802016-12-29 00:23:38692
varkor84145202018-03-27 23:13:34693 pub fn len(&self) -> usize {
694 self.0.len()
695 }
696
David Wood08ed3382021-10-08 16:10:17697 /// Returns `true` if any of the output types require codegen or linking.
Irina Popab63d7e22018-05-08 13:10:16698 pub fn should_codegen(&self) -> bool {
Nick Cameronb059a802016-12-29 00:23:38699 self.0.keys().any(|k| match *k {
Santiago Pastorino52a47d42018-03-06 05:29:03700 OutputType::Bitcode
Augie Fackleraa918712024-01-19 19:42:43701 | OutputType::ThinLinkBitcode
Santiago Pastorino52a47d42018-03-06 05:29:03702 | OutputType::Assembly
703 | OutputType::LlvmAssembly
704 | OutputType::Mir
705 | OutputType::Object
706 | OutputType::Exe => true,
707 OutputType::Metadata | OutputType::DepInfo => false,
Nick Cameronb059a802016-12-29 00:23:38708 })
709 }
Miguel Ojedaf9275e12021-01-17 14:06:47710
David Wood08ed3382021-10-08 16:10:17711 /// Returns `true` if any of the output types require linking.
Miguel Ojedaf9275e12021-01-17 14:06:47712 pub fn should_link(&self) -> bool {
713 self.0.keys().any(|k| match *k {
714 OutputType::Bitcode
Augie Fackleraa918712024-01-19 19:42:43715 | OutputType::ThinLinkBitcode
Miguel Ojedaf9275e12021-01-17 14:06:47716 | OutputType::Assembly
717 | OutputType::LlvmAssembly
718 | OutputType::Mir
719 | OutputType::Metadata
720 | OutputType::Object
721 | OutputType::DepInfo => false,
722 OutputType::Exe => true,
723 })
724 }
Brian Andersonc27133e2015-01-06 14:26:08725}
726
Alexander Regueiroc1d29ee2019-09-06 02:57:44727/// Use tree-based collections to cheaply get a deterministic `Hash` implementation.
728/// *Do not* switch `BTreeMap` or `BTreeSet` out for an unsorted container type! That
729/// would break dependency tracking for command-line arguments.
Nicholas Nethercoteac6daed2019-10-20 04:54:53730#[derive(Clone)]
Aaron Hill482b77a2019-04-07 22:48:40731pub struct Externs(BTreeMap<String, ExternEntry>);
Michael Woerister32414312016-08-02 20:53:58732
Eric Huss590dd7d2019-12-05 22:43:53733#[derive(Clone, Debug)]
Aaron Hill7cc3ce32019-03-25 03:06:32734pub struct ExternEntry {
Eric Huss590dd7d2019-12-05 22:43:53735 pub location: ExternLocation,
736 /// Indicates this is a "private" dependency for the
737 /// `exported_private_dependencies` lint.
738 ///
739 /// This can be set with the `priv` option like
740 /// `--extern priv:name=foo.rlib`.
741 pub is_private_dep: bool,
742 /// Add the extern entry to the extern prelude.
743 ///
744 /// This can be disabled with the `noprelude` option like
745 /// `--extern noprelude:name`.
746 pub add_prelude: bool,
Jeremy Fitzhardinge9102edf2022-04-14 22:09:00747 /// The extern entry shouldn't be considered for unused dependency warnings.
748 ///
749 /// `--extern nounused:std=/path/to/lib/libstd.rlib`. This is used to
750 /// suppress `unused-crate-dependencies` warnings.
751 pub nounused_dep: bool,
Matt Hammerly812f2d72023-03-14 03:55:43752 /// If the extern entry is not referenced in the crate, force it to be resolved anyway.
753 ///
754 /// Allows a dependency satisfying, for instance, a missing panic handler to be injected
755 /// without modifying source:
756 /// `--extern force:extras=/path/to/lib/libstd.rlib`
757 pub force: bool,
Eric Huss590dd7d2019-12-05 22:43:53758}
759
760#[derive(Clone, Debug)]
761pub enum ExternLocation {
762 /// Indicates to look for the library in the search paths.
763 ///
764 /// Added via `--extern name`.
765 FoundInLibrarySearchDirectories,
766 /// The locations where this extern entry must be found.
767 ///
768 /// The `CrateLoader` is responsible for loading these and figuring out
769 /// which one to use.
770 ///
771 /// Added via `--extern prelude_name=some_file.rlib`
Ryan Levick6c7ecd02021-01-26 21:27:42772 ExactPaths(BTreeSet<CanonicalizedPath>),
Aaron Hill7cc3ce32019-03-25 03:06:32773}
Aaron Hill21491dc2019-03-21 03:27:08774
Michael Woerister32414312016-08-02 20:53:58775impl Externs {
Joshua Nelson441dc362021-03-16 05:50:34776 /// Used for testing.
Aaron Hill482b77a2019-04-07 22:48:40777 pub fn new(data: BTreeMap<String, ExternEntry>) -> Externs {
Michael Woerister32414312016-08-02 20:53:58778 Externs(data)
779 }
780
Aaron Hill482b77a2019-04-07 22:48:40781 pub fn get(&self, key: &str) -> Option<&ExternEntry> {
Michael Woerister32414312016-08-02 20:53:58782 self.0.get(key)
783 }
784
Jeremy Stuckid28832d2019-06-21 21:49:03785 pub fn iter(&self) -> BTreeMapIter<'_, String, ExternEntry> {
Aaron Hill21491dc2019-03-21 03:27:08786 self.0.iter()
787 }
788}
789
Eric Huss590dd7d2019-12-05 22:43:53790impl ExternEntry {
791 fn new(location: ExternLocation) -> ExternEntry {
Matt Hammerly812f2d72023-03-14 03:55:43792 ExternEntry {
793 location,
794 is_private_dep: false,
795 add_prelude: false,
796 nounused_dep: false,
797 force: false,
798 }
Eric Huss590dd7d2019-12-05 22:43:53799 }
800
Ryan Levick6c7ecd02021-01-26 21:27:42801 pub fn files(&self) -> Option<impl Iterator<Item = &CanonicalizedPath>> {
Eric Huss590dd7d2019-12-05 22:43:53802 match &self.location {
803 ExternLocation::ExactPaths(set) => Some(set.iter()),
804 _ => None,
805 }
806 }
807}
Aaron Hill21491dc2019-03-21 03:27:08808
David Tolnayc0dc0c62023-07-17 00:20:28809#[derive(Clone, PartialEq, Debug)]
810pub struct PrintRequest {
811 pub kind: PrintKind,
812 pub out: OutFileName,
813}
814
Robin Kruppee3f6e682017-04-30 18:33:25815#[derive(Copy, Clone, PartialEq, Eq, Debug)]
David Tolnayc0dc0c62023-07-17 00:20:28816pub enum PrintKind {
Alex Crichton117984b2014-12-16 00:03:39817 FileNames,
Noratriebba481512024-10-17 17:03:06818 HostTuple,
Alex Crichton117984b2014-12-16 00:03:39819 Sysroot,
O01eg4023e5df2020-03-01 11:33:52820 TargetLibdir,
Alex Crichton117984b2014-12-16 00:03:39821 CrateName,
Alex Crichtona1ffe6b2016-01-25 19:36:18822 Cfg,
Urgauac59bdc2024-04-22 21:47:48823 CheckCfg,
khyperia9a206a72022-09-08 13:37:15824 CallingConventions,
Jorge Aparicio0bb42092016-02-12 15:11:58825 TargetList,
Cameron Harte1efa322016-07-10 14:22:13826 TargetCPUs,
827 TargetFeatures,
828 RelocationModels,
829 CodeModels,
Amanieu d'Antrasb233a6e2017-10-31 18:24:04830 TlsModels,
Doug Goldsteinff112642016-04-07 21:36:35831 TargetSpec,
Pietro Albinief2bf6d2023-03-09 13:52:45832 AllTargetSpecs,
Kornel29206582017-08-22 20:20:42833 NativeStaticLibs,
Benjamin A. Bjørnsethbb9dee92021-04-06 19:37:49834 StackProtectorStrategies,
Josh Triplettcd626fe2021-12-06 22:09:24835 LinkArgs,
Kamil Koczurek4c3cad02022-11-07 14:21:35836 SplitDebuginfo,
BlackHoleFoxa427d412022-12-06 05:15:16837 DeploymentTarget,
Alex Crichton117984b2014-12-16 00:03:39838}
839
Michael Gouleta4974fa2023-01-02 23:12:47840#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
lcnr5d97ada2023-12-14 12:00:23841pub struct NextSolverConfig {
842 /// Whether the new trait solver should be enabled in coherence.
843 pub coherence: bool,
844 /// Whether the new trait solver should be enabled everywhere.
845 /// This is only `true` if `coherence` is also enabled.
846 pub globally: bool,
Boxy040aa582023-07-03 20:00:10847}
lcnr1a9d2d82024-09-21 07:02:51848impl Default for NextSolverConfig {
849 fn default() -> Self {
850 NextSolverConfig { coherence: true, globally: false }
851 }
852}
Boxy040aa582023-07-03 20:00:10853
Urgauc773b192024-05-03 17:17:29854#[derive(Clone)]
Niko Matsakise135fa52014-11-27 12:21:26855pub enum Input {
Alexander Regueiroc1d29ee2019-09-06 02:57:44856 /// Load source code from a file.
Alex Crichton95d90462015-02-27 05:00:43857 File(PathBuf),
Alexander Regueiroc1d29ee2019-09-06 02:57:44858 /// Load source code from a string.
mitaaea7cf902016-03-10 03:49:40859 Str {
Alexander Regueiroc1d29ee2019-09-06 02:57:44860 /// A string that is shown in place of a filename.
Oliver Schneiderd732da82017-12-14 07:09:19861 name: FileName,
Alexander Regueiroc1d29ee2019-09-06 02:57:44862 /// An anonymous string containing the source code.
mitaaea7cf902016-03-10 03:49:40863 input: String,
864 },
Niko Matsakise135fa52014-11-27 12:21:26865}
866
867impl Input {
ljedrz675f00b2018-10-10 13:30:53868 pub fn filestem(&self) -> &str {
Chris Dentonc6d948212024-08-05 22:30:13869 if let Input::File(ifile) = self {
870 // If for some reason getting the file stem as a UTF-8 string fails,
871 // then fallback to a fixed name.
872 if let Some(name) = ifile.file_stem().and_then(OsStr::to_str) {
873 return name;
874 }
Niko Matsakise135fa52014-11-27 12:21:26875 }
Chris Dentonc6d948212024-08-05 22:30:13876 "rust_out"
Niko Matsakise135fa52014-11-27 12:21:26877 }
Guillaume Gomezdadfa132018-05-10 18:13:25878
John Kåre Alsaker23a51f92018-12-08 19:30:23879 pub fn source_name(&self) -> FileName {
880 match *self {
881 Input::File(ref ifile) => ifile.clone().into(),
882 Input::Str { ref name, .. } => name.clone(),
883 }
884 }
Oli Schererf5c60142022-12-06 18:56:28885
Oli Scherer13555592023-01-16 14:27:33886 pub fn opt_path(&self) -> Option<&Path> {
Oli Schererf5c60142022-12-06 18:56:28887 match self {
Oli Scherer13555592023-01-16 14:27:33888 Input::File(file) => Some(file),
Oli Schererf5c60142022-12-06 18:56:28889 Input::Str { name, .. } => match name {
Oli Scherer13555592023-01-16 14:27:33890 FileName::Real(real) => real.local_path(),
Oli Schererf5c60142022-12-06 18:56:28891 FileName::QuoteExpansion(_) => None,
892 FileName::Anon(_) => None,
893 FileName::MacroExpansion(_) => None,
894 FileName::ProcMacroSourceCode(_) => None,
Oli Schererf5c60142022-12-06 18:56:28895 FileName::CliCrateAttr(_) => None,
896 FileName::Custom(_) => None,
Oli Scherer13555592023-01-16 14:27:33897 FileName::DocTest(path, _) => Some(path),
Oli Schererf5c60142022-12-06 18:56:28898 FileName::InlineAsm(_) => None,
899 },
900 }
901 }
Niko Matsakise135fa52014-11-27 12:21:26902}
903
bjorn398a6eaa2023-11-04 15:49:57904#[derive(Clone, Hash, Debug, HashStable_Generic, PartialEq, Encodable, Decodable)]
Jing Peng9b1a1e12023-02-26 20:27:27905pub enum OutFileName {
906 Real(PathBuf),
907 Stdout,
908}
909
910impl OutFileName {
911 pub fn parent(&self) -> Option<&Path> {
912 match *self {
913 OutFileName::Real(ref path) => path.parent(),
914 OutFileName::Stdout => None,
915 }
916 }
917
918 pub fn filestem(&self) -> Option<&OsStr> {
919 match *self {
920 OutFileName::Real(ref path) => path.file_stem(),
921 OutFileName::Stdout => Some(OsStr::new("stdout")),
922 }
923 }
924
925 pub fn is_stdout(&self) -> bool {
926 match *self {
927 OutFileName::Real(_) => false,
928 OutFileName::Stdout => true,
929 }
930 }
931
932 pub fn is_tty(&self) -> bool {
klensy31630852023-07-26 15:09:50933 use std::io::IsTerminal;
Jing Peng9b1a1e12023-02-26 20:27:27934 match *self {
935 OutFileName::Real(_) => false,
klensy31630852023-07-26 15:09:50936 OutFileName::Stdout => std::io::stdout().is_terminal(),
Jing Peng9b1a1e12023-02-26 20:27:27937 }
938 }
939
940 pub fn as_path(&self) -> &Path {
941 match *self {
942 OutFileName::Real(ref path) => path.as_ref(),
Nilstrieb21a87052023-11-21 19:07:32943 OutFileName::Stdout => Path::new("stdout"),
Jing Peng9b1a1e12023-02-26 20:27:27944 }
945 }
946
947 /// For a given output filename, return the actual name of the file that
948 /// can be used to write codegen data of type `flavor`. For real-path
949 /// output filenames, this would be trivial as we can just use the path.
950 /// Otherwise for stdout, return a temporary path so that the codegen data
951 /// may be later copied to stdout.
952 pub fn file_for_writing(
953 &self,
954 outputs: &OutputFilenames,
955 flavor: OutputType,
956 codegen_unit_name: Option<&str>,
957 ) -> PathBuf {
958 match *self {
959 OutFileName::Real(ref path) => path.clone(),
960 OutFileName::Stdout => outputs.temp_path(flavor, codegen_unit_name),
961 }
962 }
David Tolnayf2e3d3f2023-07-17 05:13:08963
964 pub fn overwrite(&self, content: &str, sess: &Session) {
965 match self {
966 OutFileName::Stdout => print!("{content}"),
967 OutFileName::Real(path) => {
968 if let Err(e) = fs::write(path, content) {
Nicholas Nethercote99472c72023-12-18 11:21:37969 sess.dcx().emit_fatal(FileWriteFail { path, err: e.to_string() });
David Tolnayf2e3d3f2023-07-17 05:13:08970 }
971 }
972 }
973 }
Jing Peng9b1a1e12023-02-26 20:27:27974}
975
bjorn398a6eaa2023-11-04 15:49:57976#[derive(Clone, Hash, Debug, HashStable_Generic, Encodable, Decodable)]
Niko Matsakise135fa52014-11-27 12:21:26977pub struct OutputFilenames {
Nicholas Nethercotede388882024-03-19 02:31:28978 pub(crate) out_directory: PathBuf,
Martin Nordholts04d81ba2023-08-11 04:20:35979 /// Crate name. Never contains '-'.
980 crate_stem: String,
981 /// Typically based on `.rs` input file name. Any '-' is preserved.
Mark Rousskov8c6067c2020-01-21 14:54:58982 filestem: String,
Jing Peng9b1a1e12023-02-26 20:27:27983 pub single_output_file: Option<OutFileName>,
Nicholas Nethercotede388882024-03-19 02:31:28984 temps_directory: Option<PathBuf>,
Michael Woerister32414312016-08-02 20:53:58985 pub outputs: OutputTypes,
Niko Matsakise135fa52014-11-27 12:21:26986}
987
Victor Dinga47fdb92020-01-23 10:48:48988pub const RLINK_EXT: &str = "rlink";
Vadim Petrochenkovd588f932017-11-03 19:41:15989pub const RUST_CGU_EXT: &str = "rcgu";
David Woode3fdae92020-09-23 16:33:54990pub const DWARF_OBJECT_EXT: &str = "dwo";
Michael Woerister65e8a132016-05-14 00:48:32991
Niko Matsakise135fa52014-11-27 12:21:26992impl OutputFilenames {
Mark Rousskovd1bb7e12020-01-21 14:50:22993 pub fn new(
994 out_directory: PathBuf,
Martin Nordholts04d81ba2023-08-11 04:20:35995 out_crate_name: String,
Mark Rousskovd1bb7e12020-01-21 14:50:22996 out_filestem: String,
Jing Peng9b1a1e12023-02-26 20:27:27997 single_output_file: Option<OutFileName>,
Tor Hovland5d1e09f2021-11-02 21:41:34998 temps_directory: Option<PathBuf>,
Mark Rousskovd1bb7e12020-01-21 14:50:22999 extra: String,
1000 outputs: OutputTypes,
1001 ) -> Self {
Mark Rousskov8c6067c2020-01-21 14:54:581002 OutputFilenames {
1003 out_directory,
1004 single_output_file,
Tor Hovland5d1e09f2021-11-02 21:41:341005 temps_directory,
Mark Rousskov8c6067c2020-01-21 14:54:581006 outputs,
Martin Nordholts04d81ba2023-08-11 04:20:351007 crate_stem: format!("{out_crate_name}{extra}"),
Jubilee Youngde66e082022-03-25 05:11:051008 filestem: format!("{out_filestem}{extra}"),
Mark Rousskov8c6067c2020-01-21 14:54:581009 }
Mark Rousskovd1bb7e12020-01-21 14:50:221010 }
1011
Jing Peng9b1a1e12023-02-26 20:27:271012 pub fn path(&self, flavor: OutputType) -> OutFileName {
Santiago Pastorino52a47d42018-03-06 05:29:031013 self.outputs
1014 .get(&flavor)
1015 .and_then(|p| p.to_owned())
Alex Crichton8c963c02015-09-30 17:08:371016 .or_else(|| self.single_output_file.clone())
Jing Peng9b1a1e12023-02-26 20:27:271017 .unwrap_or_else(|| OutFileName::Real(self.output_path(flavor)))
Tor Hovland0132adc2021-04-04 11:35:041018 }
1019
1020 /// Gets the output path where a compilation artifact of the given type
1021 /// should be placed on disk.
Nicholas Nethercotede388882024-03-19 02:31:281022 fn output_path(&self, flavor: OutputType) -> PathBuf {
Tor Hovland0132adc2021-04-04 11:35:041023 let extension = flavor.extension();
Martin Nordholts04d81ba2023-08-11 04:20:351024 match flavor {
1025 OutputType::Metadata => {
1026 self.out_directory.join(format!("lib{}.{}", self.crate_stem, extension))
1027 }
1028 _ => self.with_directory_and_extension(&self.out_directory, extension),
1029 }
Niko Matsakise135fa52014-11-27 12:21:261030 }
1031
Alexander Regueiroc3e182c2019-02-08 13:53:551032 /// Gets the path where a compilation artifact of the given type for the
Michael Woerister65e8a132016-05-14 00:48:321033 /// given codegen unit should be placed on disk. If codegen_unit_name is
1034 /// None, a path distinct from those of any codegen unit will be generated.
Santiago Pastorino52a47d42018-03-06 05:29:031035 pub fn temp_path(&self, flavor: OutputType, codegen_unit_name: Option<&str>) -> PathBuf {
Niko Matsakis2f9fff212016-07-25 14:51:141036 let extension = flavor.extension();
Michael Woerister65e8a132016-05-14 00:48:321037 self.temp_path_ext(extension, codegen_unit_name)
1038 }
1039
David Woode3fdae92020-09-23 16:33:541040 /// Like `temp_path`, but specifically for dwarf objects.
1041 pub fn temp_path_dwo(&self, codegen_unit_name: Option<&str>) -> PathBuf {
1042 self.temp_path_ext(DWARF_OBJECT_EXT, codegen_unit_name)
1043 }
1044
1045 /// Like `temp_path`, but also supports things where there is no corresponding
Alexander Regueiroc3e182c2019-02-08 13:53:551046 /// OutputType, like noopt-bitcode or lto-bitcode.
Santiago Pastorino52a47d42018-03-06 05:29:031047 pub fn temp_path_ext(&self, ext: &str, codegen_unit_name: Option<&str>) -> PathBuf {
Michael Woerister65e8a132016-05-14 00:48:321048 let mut extension = String::new();
1049
1050 if let Some(codegen_unit_name) = codegen_unit_name {
Alex Crichton4ca1b192017-07-23 15:14:381051 extension.push_str(codegen_unit_name);
Niko Matsakise135fa52014-11-27 12:21:261052 }
Michael Woerister65e8a132016-05-14 00:48:321053
1054 if !ext.is_empty() {
1055 if !extension.is_empty() {
Matthias Krüger9bb10cc2020-09-10 11:57:401056 extension.push('.');
Alex Crichton4ca1b192017-07-23 15:14:381057 extension.push_str(RUST_CGU_EXT);
Matthias Krüger9bb10cc2020-09-10 11:57:401058 extension.push('.');
Michael Woerister65e8a132016-05-14 00:48:321059 }
1060
1061 extension.push_str(ext);
1062 }
1063
Tor Hovland5d1e09f2021-11-02 21:41:341064 let temps_directory = self.temps_directory.as_ref().unwrap_or(&self.out_directory);
1065
Maybe Wafflef2b97a82022-11-29 11:01:171066 self.with_directory_and_extension(temps_directory, &extension)
Niko Matsakise135fa52014-11-27 12:21:261067 }
1068
Alex Crichton95d90462015-02-27 05:00:431069 pub fn with_extension(&self, extension: &str) -> PathBuf {
Tor Hovland5d1e09f2021-11-02 21:41:341070 self.with_directory_and_extension(&self.out_directory, extension)
1071 }
1072
Integral7eb0d842024-12-17 16:28:341073 pub fn with_directory_and_extension(&self, directory: &Path, extension: &str) -> PathBuf {
Tor Hovland5d1e09f2021-11-02 21:41:341074 let mut path = directory.join(&self.filestem);
Mark Rousskovdc971812020-01-21 14:57:501075 path.set_extension(extension);
1076 path
Niko Matsakise135fa52014-11-27 12:21:261077 }
David Woode3fdae92020-09-23 16:33:541078
1079 /// Returns the path for the Split DWARF file - this can differ depending on which Split DWARF
1080 /// mode is being used, which is the logic that this function is intended to encapsulate.
David Woodee073b52020-11-08 17:17:371081 pub fn split_dwarf_path(
David Woode3fdae92020-09-23 16:33:541082 &self,
Alex Crichtona1240432020-11-30 16:39:081083 split_debuginfo_kind: SplitDebuginfo,
David Wood08ed3382021-10-08 16:10:171084 split_dwarf_kind: SplitDwarfKind,
David Woode3fdae92020-09-23 16:33:541085 cgu_name: Option<&str>,
1086 ) -> Option<PathBuf> {
1087 let obj_out = self.temp_path(OutputType::Object, cgu_name);
1088 let dwo_out = self.temp_path_dwo(cgu_name);
David Wood08ed3382021-10-08 16:10:171089 match (split_debuginfo_kind, split_dwarf_kind) {
1090 (SplitDebuginfo::Off, SplitDwarfKind::Single | SplitDwarfKind::Split) => None,
David Woode3fdae92020-09-23 16:33:541091 // Single mode doesn't change how DWARF is emitted, but does add Split DWARF attributes
1092 // (pointing at the path which is being determined here). Use the path to the current
1093 // object file.
David Wood08ed3382021-10-08 16:10:171094 (SplitDebuginfo::Packed | SplitDebuginfo::Unpacked, SplitDwarfKind::Single) => {
1095 Some(obj_out)
1096 }
David Woode3fdae92020-09-23 16:33:541097 // Split mode emits the DWARF into a different file, use that path.
David Wood08ed3382021-10-08 16:10:171098 (SplitDebuginfo::Packed | SplitDebuginfo::Unpacked, SplitDwarfKind::Split) => {
1099 Some(dwo_out)
1100 }
David Woode3fdae92020-09-23 16:33:541101 }
1102 }
Niko Matsakise135fa52014-11-27 12:21:261103}
1104
Urgau30f94712023-08-23 09:18:201105bitflags::bitflags! {
1106 /// Scopes used to determined if it need to apply to --remap-path-prefix
Nilstriebffafcd82023-12-30 16:09:021107 #[derive(Clone, Copy, PartialEq, Eq, Hash)]
Urgau30f94712023-08-23 09:18:201108 pub struct RemapPathScopeComponents: u8 {
1109 /// Apply remappings to the expansion of std::file!() macro
1110 const MACRO = 1 << 0;
1111 /// Apply remappings to printed compiler diagnostics
1112 const DIAGNOSTICS = 1 << 1;
Alexander Cyon00de0062024-09-02 05:50:221113 /// Apply remappings to debug information
Urgau777c6b42024-03-19 12:51:221114 const DEBUGINFO = 1 << 3;
Urgau30f94712023-08-23 09:18:201115
Urgau777c6b42024-03-19 12:51:221116 /// An alias for `macro` and `debuginfo`. This ensures all paths in compiled
1117 /// executables or libraries are remapped but not elsewhere.
1118 const OBJECT = Self::MACRO.bits() | Self::DEBUGINFO.bits();
Urgau30f94712023-08-23 09:18:201119 }
1120}
1121
Noratrieba26450c2024-10-17 17:02:321122pub fn host_tuple() -> &'static str {
Niko Matsakisdc6e4142014-11-16 01:30:331123 // Get the host triple out of the build environment. This ensures that our
1124 // idea of the host triple is the same as for the set of libraries we've
Maybe Waffle6a28fb42022-11-16 20:34:161125 // actually built. We can't just take LLVM's host triple because they
Niko Matsakisdc6e4142014-11-16 01:30:331126 // normalize all ix86 architectures to i386.
1127 //
1128 // Instead of grabbing the host triple (for the current host), we grab (at
1129 // compile time) the target triple that this rustc is built with and
1130 // calling that (at runtime) the host triple.
Santiago Pastorino52a47d42018-03-06 05:29:031131 (option_env!("CFG_COMPILER_HOST_TRIPLE")).expect("CFG_COMPILER_HOST_TRIPLE")
Niko Matsakisdc6e4142014-11-16 01:30:331132}
1133
Urgaueccc9e62023-08-23 13:46:581134fn file_path_mapping(
1135 remap_path_prefix: Vec<(PathBuf, PathBuf)>,
1136 unstable_opts: &UnstableOptions,
1137) -> FilePathMapping {
1138 FilePathMapping::new(
1139 remap_path_prefix.clone(),
1140 if unstable_opts.remap_path_scope.contains(RemapPathScopeComponents::DIAGNOSTICS)
1141 && !remap_path_prefix.is_empty()
1142 {
1143 FileNameDisplayPreference::Remapped
1144 } else {
1145 FileNameDisplayPreference::Local
1146 },
1147 )
1148}
1149
Mark Rousskov5fcef252018-07-26 18:36:111150impl Default for Options {
1151 fn default() -> Options {
1152 Options {
pierwill1642fdf2021-10-31 22:05:481153 assert_incr_state: None,
Mark Rousskov5fcef252018-07-26 18:36:111154 crate_types: Vec::new(),
1155 optimize: OptLevel::No,
1156 debuginfo: DebugInfo::None,
Augie Fackleraf9e5502023-07-12 21:07:341157 debuginfo_compression: DebugInfoCompression::None,
Mark Rousskov5fcef252018-07-26 18:36:111158 lint_opts: Vec::new(),
1159 lint_cap: None,
1160 describe_lints: false,
1161 output_types: OutputTypes(BTreeMap::new()),
Nicholas Nethercotef1300612018-11-22 05:33:071162 search_paths: vec![],
Mark Rousskov5fcef252018-07-26 18:36:111163 maybe_sysroot: None,
Noratrieba26450c2024-10-17 17:02:321164 target_triple: TargetTuple::from_tuple(host_tuple()),
Mark Rousskov5fcef252018-07-26 18:36:111165 test: false,
1166 incremental: None,
Alex Macleod59f6f042023-10-13 17:28:341167 untracked_state_hash: Default::default(),
Joshua Nelson3c9765c2022-07-06 12:44:471168 unstable_opts: Default::default(),
Mark Rousskov5fcef252018-07-26 18:36:111169 prints: Vec::new(),
Vadim Petrochenkov9d18d4d2021-05-07 12:18:191170 cg: Default::default(),
Mark Rousskov5fcef252018-07-26 18:36:111171 error_format: ErrorOutputType::default(),
David Wood44c1fcc2022-07-06 10:57:411172 diagnostic_width: None,
Mark Rousskov5fcef252018-07-26 18:36:111173 externs: Externs(BTreeMap::new()),
1174 crate_name: None,
Mark Rousskov5fcef252018-07-26 18:36:111175 libs: Vec::new(),
1176 unstable_features: UnstableFeatures::Disallow,
1177 debug_assertions: true,
1178 actually_rustdoc: false,
Vadim Petrochenkovda4ce6b2023-02-06 17:57:451179 resolve_doc_links: ResolveDocLinks::None,
Nicholas Nethercote32de78c2024-01-10 01:47:221180 trimmed_def_paths: false,
Mark Rousskov5fcef252018-07-26 18:36:111181 cli_forced_codegen_units: None,
Wesley Wiser7c6345d2022-10-27 00:28:251182 cli_forced_local_thinlto_off: false,
Mark Rousskov5fcef252018-07-26 18:36:111183 remap_path_prefix: Vec::new(),
Joshua Nelson39648ea2021-04-27 16:25:121184 real_rust_source_base_dir: None,
Mark Rousskov5fcef252018-07-26 18:36:111185 edition: DEFAULT_EDITION,
Alex Crichton17312332019-07-17 19:52:561186 json_artifact_notifications: false,
Jeremy Fitzhardingec6bafa72022-04-17 00:11:331187 json_unused_externs: JsonUnusedExterns::No,
Aaron Hill63523e42021-12-04 19:34:201188 json_future_incompat: false,
Mark Rousskovdd6df0d2019-11-04 02:42:031189 pretty: None,
Aaron Hilla8950692021-08-12 20:30:401190 working_dir: RealFileName::LocalPath(std::env::current_dir().unwrap()),
Trevor Gross6a1c10b2022-12-19 18:09:401191 color: ColorConfig::Auto,
Guillaume Gomez486e55e2023-11-27 12:47:261192 logical_env: FxIndexMap::default(),
jyncb6d0332023-12-19 18:24:051193 verbose: false,
Mark Rousskov5fcef252018-07-26 18:36:111194 }
Nick Cameron37ca3672014-05-06 11:38:011195 }
1196}
1197
Niko Matsakisfe47ca02016-03-28 21:43:361198impl Options {
Alexander Regueiroc3e182c2019-02-08 13:53:551199 /// Returns `true` if there is a reason to build the dep graph.
Niko Matsakisfe47ca02016-03-28 21:43:361200 pub fn build_dep_graph(&self) -> bool {
Mark Rousskova06baa52019-12-22 22:42:041201 self.incremental.is_some()
Joshua Nelson3c9765c2022-07-06 12:44:471202 || self.unstable_opts.dump_dep_graph
1203 || self.unstable_opts.query_dep_graph
Niko Matsakisfe47ca02016-03-28 21:43:361204 }
Michael Woerister59cfe902016-07-13 21:03:021205
Nicholas Nethercote62c32ae2024-03-21 03:17:001206 pub fn file_path_mapping(&self) -> FilePathMapping {
Urgaueccc9e62023-08-23 13:46:581207 file_path_mapping(self.remap_path_prefix.clone(), &self.unstable_opts)
Michael Woerister39ffea32017-04-24 17:01:191208 }
varkorc76cdce2017-12-18 15:35:451209
Alexander Regueiroc1d29ee2019-09-06 02:57:441210 /// Returns `true` if there will be an output file generated.
varkorc76cdce2017-12-18 15:35:451211 pub fn will_create_output_file(&self) -> bool {
Nicholas Nethercote76adf052024-11-28 19:05:561212 !self.unstable_opts.parse_crate_root_only && // The file is just being parsed
bjorn3ff007632023-09-10 13:24:201213 self.unstable_opts.ls.is_empty() // The file is just being queried
varkorc76cdce2017-12-18 15:35:451214 }
Mark Rousskova9093a42018-07-26 19:20:471215
1216 #[inline]
1217 pub fn share_generics(&self) -> bool {
Joshua Nelson3c9765c2022-07-06 12:44:471218 match self.unstable_opts.share_generics {
Mark Rousskova9093a42018-07-26 19:20:471219 Some(setting) => setting,
Mark Rousskova06baa52019-12-22 22:42:041220 None => match self.optimize {
1221 OptLevel::No | OptLevel::Less | OptLevel::Size | OptLevel::SizeMin => true,
1222 OptLevel::Default | OptLevel::Aggressive => false,
1223 },
Mark Rousskova9093a42018-07-26 19:20:471224 }
1225 }
Josh Triplettbbf4b662021-10-21 12:02:591226
1227 pub fn get_symbol_mangling_version(&self) -> SymbolManglingVersion {
1228 self.cg.symbol_mangling_version.unwrap_or(SymbolManglingVersion::Legacy)
1229 }
Niko Matsakisfe47ca02016-03-28 21:43:361230}
1231
Joshua Nelson3c9765c2022-07-06 12:44:471232impl UnstableOptions {
Nicholas Nethercote55bafab2023-12-17 21:59:221233 pub fn dcx_flags(&self, can_emit_warnings: bool) -> DiagCtxtFlags {
Nicholas Nethercote9b1f87c2023-12-17 21:47:031234 DiagCtxtFlags {
Vadim Petrochenkov1370bbc2019-12-29 20:07:231235 can_emit_warnings,
1236 treat_err_as_bug: self.treat_err_as_bug,
Michael Goulet7df43d32024-01-12 00:30:041237 eagerly_emit_delayed_bugs: self.eagerly_emit_delayed_bugs,
Eduard-Mihai Burtescuf6fc8022019-12-15 15:12:301238 macro_backtrace: self.macro_backtrace,
Nicholas Nethercote58217bc2020-04-02 05:44:471239 deduplicate_diagnostics: self.deduplicate_diagnostics,
mejrs406e1dc2022-10-18 22:08:201240 track_diagnostics: self.track_diagnostics,
Vadim Petrochenkov1370bbc2019-12-29 20:07:231241 }
1242 }
Nicholas Nethercote62c32ae2024-03-21 03:17:001243
1244 pub fn src_hash_algorithm(&self, target: &Target) -> SourceFileHashAlgorithm {
1245 self.src_hash_algorithm.unwrap_or_else(|| {
1246 if target.is_like_msvc {
1247 SourceFileHashAlgorithm::Sha256
1248 } else {
1249 SourceFileHashAlgorithm::Md5
1250 }
1251 })
1252 }
Jacob Kieselbb5a8272024-06-22 07:27:591253
1254 pub fn checksum_hash_algorithm(&self) -> Option<SourceFileHashAlgorithm> {
1255 self.checksum_hash_algorithm
1256 }
Vadim Petrochenkov208c1bf2019-12-29 21:23:191257}
1258
Igor Matuszewskiff19a532019-01-13 12:06:261259// The type of entry function, so users can have their own entry functions
Michael Woeristerc0be6192022-04-19 08:43:091260#[derive(Copy, Clone, PartialEq, Hash, Debug, HashStable_Generic)]
Nick Cameron37ca3672014-05-06 11:38:011261pub enum EntryFnType {
Martin Nordholtsddee45e2022-07-05 17:56:221262 Main {
1263 /// Specifies what to do with `SIGPIPE` before calling `fn main()`.
1264 ///
1265 /// What values that are valid and what they mean must be in sync
1266 /// across rustc and libstd, but we don't want it public in libstd,
1267 /// so we take a bit of an unusual approach with simple constants
1268 /// and an `include!()`.
1269 sigpipe: u8,
1270 },
Mark Rousskov442a4742018-07-26 17:29:451271 Start,
Nick Cameron37ca3672014-05-06 11:38:011272}
1273
Matthew Jaspercbcef3e2020-06-11 14:49:571274#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, Encodable, Decodable)]
Michael Woeristerc0be6192022-04-19 08:43:091275#[derive(HashStable_Generic)]
Nick Cameron37ca3672014-05-06 11:38:011276pub enum CrateType {
Mark Rousskov2a934422018-07-26 17:13:111277 Executable,
1278 Dylib,
1279 Rlib,
1280 Staticlib,
1281 Cdylib,
1282 ProcMacro,
Nick Cameron37ca3672014-05-06 11:38:011283}
1284
Vadim Petrochenkovda4ce6b2023-02-06 17:57:451285impl CrateType {
1286 pub fn has_metadata(self) -> bool {
1287 match self {
1288 CrateType::Rlib | CrateType::Dylib | CrateType::ProcMacro => true,
1289 CrateType::Executable | CrateType::Cdylib | CrateType::Staticlib => false,
1290 }
1291 }
1292}
1293
Joshua Nelsonfb7018b2021-04-16 03:06:321294#[derive(Clone, Hash, Debug, PartialEq, Eq)]
Keegan McAllisterad9a1da2014-09-12 15:17:581295pub enum Passes {
Mark Rousskovb3267dc2018-07-26 17:22:141296 Some(Vec<String>),
1297 All,
Keegan McAllisterad9a1da2014-09-12 15:17:581298}
1299
1300impl Passes {
Nicholas Nethercotede388882024-03-19 02:31:281301 fn is_empty(&self) -> bool {
Keegan McAllisterad9a1da2014-09-12 15:17:581302 match *self {
Mark Rousskovb3267dc2018-07-26 17:22:141303 Passes::Some(ref v) => v.is_empty(),
1304 Passes::All => false,
Keegan McAllisterad9a1da2014-09-12 15:17:581305 }
1306 }
Tomasz Miąskoe74e39a2021-11-13 00:00:001307
Nicholas Nethercotede388882024-03-19 02:31:281308 pub(crate) fn extend(&mut self, passes: impl IntoIterator<Item = String>) {
Tomasz Miąskoe74e39a2021-11-13 00:00:001309 match *self {
1310 Passes::Some(ref mut v) => v.extend(passes),
1311 Passes::All => {}
1312 }
1313 }
Keegan McAllisterad9a1da2014-09-12 15:17:581314}
1315
James McGregor837cc162021-07-13 11:14:261316#[derive(Clone, Copy, Hash, Debug, PartialEq)]
1317pub enum PAuthKey {
1318 A,
1319 B,
1320}
1321
1322#[derive(Clone, Copy, Hash, Debug, PartialEq)]
1323pub struct PacRet {
1324 pub leaf: bool,
Kajetan Puchalski10edeea2024-10-16 14:39:581325 pub pc: bool,
James McGregor837cc162021-07-13 11:14:261326 pub key: PAuthKey,
1327}
1328
Matthias Krügerde598442022-12-14 23:06:341329#[derive(Clone, Copy, Hash, Debug, PartialEq, Default)]
James McGregor837cc162021-07-13 11:14:261330pub struct BranchProtection {
1331 pub bti: bool,
1332 pub pac_ret: Option<PacRet>,
1333}
1334
Nicholas Nethercotede388882024-03-19 02:31:281335pub(crate) const fn default_lib_output() -> CrateType {
Mark Rousskov2a934422018-07-26 17:13:111336 CrateType::Rlib
Nick Cameron37ca3672014-05-06 11:38:011337}
1338
Nicholas Nethercote5c6a12c2023-10-30 03:05:061339pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg {
Urgauc0c57b32024-06-08 11:26:371340 // First disallow some configuration given on the command line
1341 cfg::disallow_cfgs(sess, &user_cfg);
1342
1343 // Then combine the configuration requested by the session (command line) with
Alexander Regueiroc1d29ee2019-09-06 02:57:441344 // some default and generated configuration items.
Urgau5b144972024-04-05 21:01:401345 user_cfg.extend(cfg::default_configuration(sess));
Jeffrey Seyfried4b9b0d32016-11-15 08:54:271346 user_cfg
Nick Cameron37ca3672014-05-06 11:38:011347}
1348
Nicholas Nethercote23ee523e2024-03-20 23:35:191349pub fn build_target_config(early_dcx: &EarlyDiagCtxt, opts: &Options, sysroot: &Path) -> Target {
1350 match Target::search(&opts.target_triple, sysroot) {
1351 Ok((target, warnings)) => {
1352 for warning in warnings.warning_messages() {
1353 early_dcx.early_warn(warning)
1354 }
Alex Crichtone003a122024-06-19 03:54:111355
Nicholas Nethercote23ee523e2024-03-20 23:35:191356 if !matches!(target.pointer_width, 16 | 32 | 64) {
1357 early_dcx.early_fatal(format!(
1358 "target specification was invalid: unrecognized target-pointer-width {}",
1359 target.pointer_width
1360 ))
1361 }
1362 target
1363 }
1364 Err(e) => early_dcx.early_fatal(format!(
Matthias Krüger23815462023-07-25 20:00:131365 "Error loading target specification: {e}. \
Nicholas Nethercote23ee523e2024-03-20 23:35:191366 Run `rustc --print target-list` for a list of built-in targets"
1367 )),
Adam Bratschi-Kaye88b01f12021-05-27 08:21:531368 }
Nick Cameron37ca3672014-05-06 11:38:011369}
1370
Jorge Aparicio788181d2015-01-28 13:34:181371#[derive(Copy, Clone, PartialEq, Eq, Debug)]
Zalathar001013c2024-11-07 11:47:151372pub enum OptionStability {
Alex Crichton12828332016-02-20 06:03:541373 Stable,
Alex Crichton12828332016-02-20 06:03:541374 Unstable,
1375}
Felix S. Klock IIe711e2d2014-12-17 13:42:501376
Zalathar001013c2024-11-07 11:47:151377#[derive(Copy, Clone, PartialEq, Eq, Debug)]
1378pub enum OptionKind {
1379 /// An option that takes a value, and cannot appear more than once (e.g. `--out-dir`).
1380 ///
1381 /// Corresponds to [`getopts::Options::optopt`].
1382 Opt,
1383
1384 /// An option that takes a value, and can appear multiple times (e.g. `--emit`).
1385 ///
1386 /// Corresponds to [`getopts::Options::optmulti`].
1387 Multi,
1388
1389 /// An option that does not take a value, and cannot appear more than once (e.g. `--help`).
1390 ///
1391 /// Corresponds to [`getopts::Options::optflag`].
1392 /// The `hint` string must be empty.
1393 Flag,
1394
1395 /// An option that does not take a value, and can appear multiple times (e.g. `-O`).
1396 ///
1397 /// Corresponds to [`getopts::Options::optflagmulti`].
1398 /// The `hint` string must be empty.
1399 FlagMulti,
1400}
1401
Felix S. Klock IIe711e2d2014-12-17 13:42:501402pub struct RustcOptGroup {
Zalathar3250c1c2024-11-11 02:05:531403 /// The "primary" name for this option. Normally equal to `long_name`,
1404 /// except for options that don't have a long name, in which case
1405 /// `short_name` is used.
1406 ///
1407 /// This is needed when interacting with `getopts` in some situations,
1408 /// because if an option has both forms, that library treats the long name
1409 /// as primary and the short name as an alias.
George Bateman63602872024-08-11 08:07:521410 pub name: &'static str,
Nicholas Nethercotede388882024-03-19 02:31:281411 stability: OptionStability,
Zalathar3250c1c2024-11-11 02:05:531412 kind: OptionKind,
1413
1414 short_name: &'static str,
1415 long_name: &'static str,
1416 desc: &'static str,
1417 value_hint: &'static str,
Zalathar8b4701d2024-11-11 02:17:391418
1419 /// If true, this option should not be printed by `rustc --help`, but
1420 /// should still be printed by `rustc --help -v`.
1421 pub is_verbose_help_only: bool,
Felix S. Klock IIe711e2d2014-12-17 13:42:501422}
1423
1424impl RustcOptGroup {
1425 pub fn is_stable(&self) -> bool {
1426 self.stability == OptionStability::Stable
1427 }
1428
Zalathar584c8202024-11-08 01:20:511429 pub fn apply(&self, options: &mut getopts::Options) {
Zalathar3250c1c2024-11-11 02:05:531430 let &Self { short_name, long_name, desc, value_hint, .. } = self;
1431 match self.kind {
1432 OptionKind::Opt => options.optopt(short_name, long_name, desc, value_hint),
1433 OptionKind::Multi => options.optmulti(short_name, long_name, desc, value_hint),
1434 OptionKind::Flag => options.optflag(short_name, long_name, desc),
1435 OptionKind::FlagMulti => options.optflagmulti(short_name, long_name, desc),
1436 };
Zalathar584c8202024-11-08 01:20:511437 }
Felix S. Klock IIe711e2d2014-12-17 13:42:501438}
1439
Zalathar001013c2024-11-07 11:47:151440pub fn make_opt(
1441 stability: OptionStability,
1442 kind: OptionKind,
1443 short_name: &'static str,
1444 long_name: &'static str,
1445 desc: &'static str,
Zalathar3250c1c2024-11-11 02:05:531446 value_hint: &'static str,
Zalathar001013c2024-11-07 11:47:151447) -> RustcOptGroup {
Zalathar3250c1c2024-11-11 02:05:531448 // "Flag" options don't have a value, and therefore don't have a value hint.
1449 match kind {
1450 OptionKind::Opt | OptionKind::Multi => {}
1451 OptionKind::Flag | OptionKind::FlagMulti => assert_eq!(value_hint, ""),
1452 }
Zalathar001013c2024-11-07 11:47:151453 RustcOptGroup {
1454 name: cmp::max_by_key(short_name, long_name, |s| s.len()),
1455 stability,
Zalathar3250c1c2024-11-11 02:05:531456 kind,
1457 short_name,
1458 long_name,
1459 desc,
1460 value_hint,
Zalathar8b4701d2024-11-11 02:17:391461 is_verbose_help_only: false,
Alex Crichton12828332016-02-20 06:03:541462 }
Felix S. Klock IIe711e2d2014-12-17 13:42:501463}
Nicholas Nethercotede388882024-03-19 02:31:281464
Matthew Esposito5cda0a22023-01-06 19:07:121465static EDITION_STRING: LazyLock<String> = LazyLock::new(|| {
1466 format!(
Matthew E893938f2023-01-06 19:36:521467 "Specify which edition of the compiler to use when compiling code. \
Matthew Esposito5cda0a22023-01-06 19:07:121468The default is {DEFAULT_EDITION} and the latest stable edition is {LATEST_STABLE_EDITION}."
1469 )
1470});
Nicholas Nethercotede388882024-03-19 02:31:281471
Zalathar8b4701d2024-11-11 02:17:391472/// Returns all rustc command line options, including metadata for
1473/// each option, such as whether the option is stable.
1474pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
Zalathar001013c2024-11-07 11:47:151475 use OptionKind::{Flag, FlagMulti, Multi, Opt};
Zalathar8b4701d2024-11-11 02:17:391476 use OptionStability::{Stable, Unstable};
Zalathar001013c2024-11-07 11:47:151477
1478 use self::make_opt as opt;
1479
Zalathar8b4701d2024-11-11 02:17:391480 let mut options = vec![
Zalathar001013c2024-11-07 11:47:151481 opt(Stable, Flag, "h", "help", "Display this message", ""),
1482 opt(
1483 Stable,
1484 Multi,
1485 "",
1486 "cfg",
1487 "Configure the compilation environment.\n\
1488 SPEC supports the syntax `NAME[=\"VALUE\"]`.",
1489 "SPEC",
1490 ),
1491 opt(Stable, Multi, "", "check-cfg", "Provide list of expected cfgs for checking", "SPEC"),
1492 opt(
1493 Stable,
1494 Multi,
Santiago Pastorino52a47d42018-03-06 05:29:031495 "L",
1496 "",
Zalathar001013c2024-11-07 11:47:151497 "Add a directory to the library search path. \
1498 The optional KIND can be one of dependency, crate, native, framework, or all (the default).",
Santiago Pastorino52a47d42018-03-06 05:29:031499 "[KIND=]PATH",
1500 ),
Zalathar001013c2024-11-07 11:47:151501 opt(
1502 Stable,
1503 Multi,
Santiago Pastorino52a47d42018-03-06 05:29:031504 "l",
1505 "",
Zalathar001013c2024-11-07 11:47:151506 "Link the generated crate(s) to the specified native\n\
1507 library NAME. The optional KIND can be one of\n\
1508 static, framework, or dylib (the default).\n\
1509 Optional comma separated MODIFIERS\n\
1510 (bundle|verbatim|whole-archive|as-needed)\n\
1511 may be specified each with a prefix of either '+' to\n\
1512 enable or '-' to disable.",
Luqman Adendb555e12021-03-25 04:45:091513 "[KIND[:MODIFIERS]=]NAME[:RENAME]",
Santiago Pastorino52a47d42018-03-06 05:29:031514 ),
Aaron Hill14986082019-07-20 20:34:411515 make_crate_type_option(),
Zalathar001013c2024-11-07 11:47:151516 opt(Stable, Opt, "", "crate-name", "Specify the name of the crate being built", "NAME"),
1517 opt(Stable, Opt, "", "edition", &EDITION_STRING, EDITION_NAME_LIST),
1518 opt(
1519 Stable,
1520 Multi,
Santiago Pastorino52a47d42018-03-06 05:29:031521 "",
1522 "emit",
Zalathar001013c2024-11-07 11:47:151523 "Comma separated list of types of output for the compiler to emit",
Santiago Pastorino52a47d42018-03-06 05:29:031524 "[asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]",
1525 ),
Zalathar001013c2024-11-07 11:47:151526 opt(
1527 Stable,
1528 Multi,
Santiago Pastorino52a47d42018-03-06 05:29:031529 "",
1530 "print",
Eric Husse392db62019-05-12 21:16:501531 "Compiler information to print on stdout",
Urgauac59bdc2024-04-22 21:47:481532 "[crate-name|file-names|sysroot|target-libdir|cfg|check-cfg|calling-conventions|\
khyperia9a206a72022-09-08 13:37:151533 target-list|target-cpus|target-features|relocation-models|code-models|\
Pietro Albinief2bf6d2023-03-09 13:52:451534 tls-models|target-spec-json|all-target-specs-json|native-static-libs|\
BlackHoleFoxa427d412022-12-06 05:15:161535 stack-protector-strategies|link-args|deployment-target]",
Santiago Pastorino52a47d42018-03-06 05:29:031536 ),
Zalathar001013c2024-11-07 11:47:151537 opt(Stable, FlagMulti, "g", "", "Equivalent to -C debuginfo=2", ""),
1538 opt(Stable, FlagMulti, "O", "", "Equivalent to -C opt-level=2", ""),
1539 opt(Stable, Opt, "o", "", "Write output to <filename>", "FILENAME"),
1540 opt(Stable, Opt, "", "out-dir", "Write output to compiler-chosen filename in <dir>", "DIR"),
1541 opt(
1542 Stable,
1543 Opt,
Santiago Pastorino52a47d42018-03-06 05:29:031544 "",
1545 "explain",
Zalathar001013c2024-11-07 11:47:151546 "Provide a detailed explanation of an error message",
Santiago Pastorino52a47d42018-03-06 05:29:031547 "OPT",
1548 ),
Zalathar001013c2024-11-07 11:47:151549 opt(Stable, Flag, "", "test", "Build a test harness", ""),
1550 opt(Stable, Opt, "", "target", "Target triple for which the code is compiled", "TARGET"),
1551 opt(Stable, Multi, "A", "allow", "Set lint allowed", "LINT"),
1552 opt(Stable, Multi, "W", "warn", "Set lint warnings", "LINT"),
1553 opt(Stable, Multi, "", "force-warn", "Set lint force-warn", "LINT"),
1554 opt(Stable, Multi, "D", "deny", "Set lint denied", "LINT"),
1555 opt(Stable, Multi, "F", "forbid", "Set lint forbidden", "LINT"),
1556 opt(
1557 Stable,
1558 Multi,
Santiago Pastorino52a47d42018-03-06 05:29:031559 "",
1560 "cap-lints",
Zalathar001013c2024-11-07 11:47:151561 "Set the most restrictive lint level. More restrictive lints are capped at this level",
Santiago Pastorino52a47d42018-03-06 05:29:031562 "LEVEL",
1563 ),
Zalathar001013c2024-11-07 11:47:151564 opt(Stable, Multi, "C", "codegen", "Set a codegen option", "OPT[=VALUE]"),
1565 opt(Stable, Flag, "V", "version", "Print version info and exit", ""),
1566 opt(Stable, Flag, "v", "verbose", "Use verbose output", ""),
Zalathar8b4701d2024-11-11 02:17:391567 ];
Alex Crichton117984b2014-12-16 00:03:391568
Zalathar8b4701d2024-11-11 02:17:391569 // Options in this list are hidden from `rustc --help` by default, but are
1570 // shown by `rustc --help -v`.
1571 let verbose_only = [
Zalathar001013c2024-11-07 11:47:151572 opt(
1573 Stable,
1574 Multi,
Santiago Pastorino52a47d42018-03-06 05:29:031575 "",
1576 "extern",
1577 "Specify where an external rust library is located",
Eric Huss4bf411e2019-09-30 01:17:481578 "NAME[=PATH]",
Santiago Pastorino52a47d42018-03-06 05:29:031579 ),
Zalathar001013c2024-11-07 11:47:151580 opt(Stable, Opt, "", "sysroot", "Override the system root", "PATH"),
1581 opt(Unstable, Multi, "Z", "", "Set unstable / perma-unstable options", "FLAG"),
1582 opt(
1583 Stable,
1584 Opt,
Santiago Pastorino52a47d42018-03-06 05:29:031585 "",
1586 "error-format",
1587 "How errors and other messages are produced",
1588 "human|json|short",
1589 ),
Zalathar001013c2024-11-07 11:47:151590 opt(Stable, Multi, "", "json", "Configure the JSON output of the compiler", "CONFIG"),
1591 opt(
1592 Stable,
1593 Opt,
Santiago Pastorino52a47d42018-03-06 05:29:031594 "",
1595 "color",
1596 "Configure coloring of output:
Zalathar8b4701d2024-11-11 02:17:391597 auto = colorize, if output goes to a tty (default);
1598 always = always colorize output;
1599 never = never colorize output",
Santiago Pastorino52a47d42018-03-06 05:29:031600 "auto|always|never",
1601 ),
Zalathar001013c2024-11-07 11:47:151602 opt(
1603 Stable,
1604 Opt,
David Woode5288842022-02-14 06:01:381605 "",
David Wood44c1fcc2022-07-06 10:57:411606 "diagnostic-width",
1607 "Inform rustc of the width of the output so that diagnostics can be truncated to fit",
David Woode5288842022-02-14 06:01:381608 "WIDTH",
1609 ),
Zalathar001013c2024-11-07 11:47:151610 opt(
1611 Stable,
1612 Multi,
Santiago Pastorino52a47d42018-03-06 05:29:031613 "",
1614 "remap-path-prefix",
Jeremy Fitzhardinge6d534d52018-03-13 20:26:071615 "Remap source names in all output (compiler messages and output files)",
Santiago Pastorino52a47d42018-03-06 05:29:031616 "FROM=TO",
1617 ),
Zalathar001013c2024-11-07 11:47:151618 opt(Unstable, Multi, "", "env-set", "Inject an environment variable", "VAR=VALUE"),
Zalathar8b4701d2024-11-11 02:17:391619 ];
1620 options.extend(verbose_only.into_iter().map(|mut opt| {
1621 opt.is_verbose_help_only = true;
1622 opt
1623 }));
1624
1625 options
Nick Cameron37ca3672014-05-06 11:38:011626}
1627
Mark Rousskova06baa52019-12-22 22:42:041628pub fn get_cmd_lint_options(
Nicholas Nethercoted58e3722023-12-17 23:57:261629 early_dcx: &EarlyDiagCtxt,
Mark Rousskova06baa52019-12-22 22:42:041630 matches: &getopts::Matches,
inquisitivecrystal2f2db992021-07-08 07:05:381631) -> (Vec<(String, lint::Level)>, bool, Option<lint::Level>) {
Tobias Thiel51021b12020-01-05 02:04:301632 let mut lint_opts_with_position = vec![];
Guillaume Gomeze221be82018-06-23 13:09:211633 let mut describe_lints = false;
1634
xFrednet8527a3d2022-06-05 10:33:451635 for level in [lint::Allow, lint::Warn, lint::ForceWarn(None), lint::Deny, lint::Forbid] {
inquisitivecrystal2f2db992021-07-08 07:05:381636 for (arg_pos, lint_name) in matches.opt_strs_pos(level.as_str()) {
Guillaume Gomeze221be82018-06-23 13:09:211637 if lint_name == "help" {
1638 describe_lints = true;
1639 } else {
Matthias Krüger97e844a2021-12-13 21:58:581640 lint_opts_with_position.push((arg_pos, lint_name.replace('-', "_"), level));
Guillaume Gomeze221be82018-06-23 13:09:211641 }
1642 }
1643 }
1644
Tobias Thiel51021b12020-01-05 02:04:301645 lint_opts_with_position.sort_by_key(|x| x.0);
1646 let lint_opts = lint_opts_with_position
1647 .iter()
1648 .cloned()
1649 .map(|(_, lint_name, level)| (lint_name, level))
1650 .collect();
1651
Guillaume Gomeze221be82018-06-23 13:09:211652 let lint_cap = matches.opt_str("cap-lints").map(|cap| {
1653 lint::Level::from_str(&cap)
Nicholas Nethercote3a1b8e62023-12-20 03:53:501654 .unwrap_or_else(|| early_dcx.early_fatal(format!("unknown lint level: `{cap}`")))
Guillaume Gomeze221be82018-06-23 13:09:211655 });
Ryan Levick69a19bf2021-05-27 17:19:391656
inquisitivecrystal2f2db992021-07-08 07:05:381657 (lint_opts, describe_lints, lint_cap)
Guillaume Gomeze221be82018-06-23 13:09:211658}
1659
Alexander Regueiroc1d29ee2019-09-06 02:57:441660/// Parses the `--color` flag.
Nicholas Nethercoted58e3722023-12-17 23:57:261661pub fn parse_color(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> ColorConfig {
Maybe Waffle94470f42022-11-16 21:58:581662 match matches.opt_str("color").as_deref() {
Santiago Pastorino52a47d42018-03-06 05:29:031663 Some("auto") => ColorConfig::Auto,
Nick Cameron6309b0f2015-12-13 22:17:551664 Some("always") => ColorConfig::Always,
Santiago Pastorino52a47d42018-03-06 05:29:031665 Some("never") => ColorConfig::Never,
Barosl Lee71f39c1a2015-08-22 14:51:531666
Nick Cameron6309b0f2015-12-13 22:17:551667 None => ColorConfig::Auto,
Barosl Lee71f39c1a2015-08-22 14:51:531668
Nicholas Nethercote3a1b8e62023-12-20 03:53:501669 Some(arg) => early_dcx.early_fatal(format!(
许杰友 Jieyou Xu (Joe)cef812b2023-06-22 21:56:091670 "argument for `--color` must be auto, \
Jubilee Youngde66e082022-03-25 05:11:051671 always or never (instead was `{arg}`)"
许杰友 Jieyou Xu (Joe)cef812b2023-06-22 21:56:091672 )),
Alex Crichton17312332019-07-17 19:52:561673 }
1674}
Barosl Lee71f39c1a2015-08-22 14:51:531675
est312d520062020-07-05 17:35:461676/// Possible json config files
1677pub struct JsonConfig {
1678 pub json_rendered: HumanReadableErrorType,
Esteban Küberae696f82024-08-08 01:46:161679 pub json_color: ColorConfig,
Nicholas Nethercotede388882024-03-19 02:31:281680 json_artifact_notifications: bool,
Jeremy Fitzhardingec6bafa72022-04-17 00:11:331681 pub json_unused_externs: JsonUnusedExterns,
Nicholas Nethercotede388882024-03-19 02:31:281682 json_future_incompat: bool,
est312d520062020-07-05 17:35:461683}
1684
Jeremy Fitzhardingec6bafa72022-04-17 00:11:331685/// Report unused externs in event stream
1686#[derive(Copy, Clone)]
1687pub enum JsonUnusedExterns {
1688 /// Do not
1689 No,
1690 /// Report, but do not exit with failure status for deny/forbid
1691 Silent,
1692 /// Report, and also exit with failure status for deny/forbid
1693 Loud,
1694}
1695
1696impl JsonUnusedExterns {
1697 pub fn is_enabled(&self) -> bool {
1698 match self {
1699 JsonUnusedExterns::No => false,
1700 JsonUnusedExterns::Loud | JsonUnusedExterns::Silent => true,
1701 }
1702 }
1703
1704 pub fn is_loud(&self) -> bool {
1705 match self {
1706 JsonUnusedExterns::No | JsonUnusedExterns::Silent => false,
1707 JsonUnusedExterns::Loud => true,
1708 }
1709 }
1710}
1711
Alex Crichton17312332019-07-17 19:52:561712/// Parse the `--json` flag.
1713///
1714/// The first value returned is how to render JSON diagnostics, and the second
1715/// is whether or not artifact notifications are enabled.
Nicholas Nethercoted58e3722023-12-17 23:57:261716pub fn parse_json(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> JsonConfig {
Esteban Küberae696f82024-08-08 01:46:161717 let mut json_rendered = HumanReadableErrorType::Default;
Alex Crichton17312332019-07-17 19:52:561718 let mut json_color = ColorConfig::Never;
1719 let mut json_artifact_notifications = false;
Jeremy Fitzhardingec6bafa72022-04-17 00:11:331720 let mut json_unused_externs = JsonUnusedExterns::No;
Aaron Hill63523e42021-12-04 19:34:201721 let mut json_future_incompat = false;
Alex Crichton17312332019-07-17 19:52:561722 for option in matches.opt_strs("json") {
1723 // For now conservatively forbid `--color` with `--json` since `--json`
1724 // won't actually be emitting any colors and anything colorized is
1725 // embedded in a diagnostic message anyway.
1726 if matches.opt_str("color").is_some() {
Nicholas Nethercote3a1b8e62023-12-20 03:53:501727 early_dcx.early_fatal("cannot specify the `--color` option with `--json`");
Alex Crichton17312332019-07-17 19:52:561728 }
Kurtis Nusbaum51f51102018-04-19 20:56:261729
Alex Crichton17312332019-07-17 19:52:561730 for sub_option in option.split(',') {
1731 match sub_option {
1732 "diagnostic-short" => json_rendered = HumanReadableErrorType::Short,
Esteban Küber1d780042024-06-17 15:14:071733 "diagnostic-unicode" => {
1734 json_rendered = HumanReadableErrorType::Unicode;
1735 }
Alex Crichton17312332019-07-17 19:52:561736 "diagnostic-rendered-ansi" => json_color = ColorConfig::Always,
1737 "artifacts" => json_artifact_notifications = true,
Jeremy Fitzhardingec6bafa72022-04-17 00:11:331738 "unused-externs" => json_unused_externs = JsonUnusedExterns::Loud,
1739 "unused-externs-silent" => json_unused_externs = JsonUnusedExterns::Silent,
Aaron Hill63523e42021-12-04 19:34:201740 "future-incompat" => json_future_incompat = true,
Nicholas Nethercote3a1b8e62023-12-20 03:53:501741 s => early_dcx.early_fatal(format!("unknown `--json` option `{s}`")),
Alex Crichton17312332019-07-17 19:52:561742 }
1743 }
Kurtis Nusbaum320fdaa2018-04-20 04:03:211744 }
est312d520062020-07-05 17:35:461745
1746 JsonConfig {
Esteban Küberae696f82024-08-08 01:46:161747 json_rendered,
1748 json_color,
est312d520062020-07-05 17:35:461749 json_artifact_notifications,
1750 json_unused_externs,
Aaron Hill63523e42021-12-04 19:34:201751 json_future_incompat,
est312d520062020-07-05 17:35:461752 }
Alex Crichton17312332019-07-17 19:52:561753}
Kurtis Nusbaum320fdaa2018-04-20 04:03:211754
Alexander Regueiroc1d29ee2019-09-06 02:57:441755/// Parses the `--error-format` flag.
Alex Crichton17312332019-07-17 19:52:561756pub fn parse_error_format(
Nicholas Nethercoted58e3722023-12-17 23:57:261757 early_dcx: &mut EarlyDiagCtxt,
Alex Crichton17312332019-07-17 19:52:561758 matches: &getopts::Matches,
1759 color: ColorConfig,
Esteban Küberae696f82024-08-08 01:46:161760 json_color: ColorConfig,
Alex Crichton17312332019-07-17 19:52:561761 json_rendered: HumanReadableErrorType,
1762) -> ErrorOutputType {
Alexander Regueiroc1d29ee2019-09-06 02:57:441763 // We need the `opts_present` check because the driver will send us Matches
Nick Cameron82f8e5c2016-01-06 20:23:011764 // with only stable options if no unstable options are used. Since error-format
Alexander Regueiroc1d29ee2019-09-06 02:57:441765 // is unstable, it will not be present. We have to use `opts_present` not
1766 // `opt_present` because the latter will panic.
Nick Cameron82f8e5c2016-01-06 20:23:011767 let error_format = if matches.opts_present(&["error-format".to_owned()]) {
Maybe Waffle94470f42022-11-16 21:58:581768 match matches.opt_str("error-format").as_deref() {
Mark Rousskova06baa52019-12-22 22:42:041769 None | Some("human") => {
Esteban Küberae696f82024-08-08 01:46:161770 ErrorOutputType::HumanReadable(HumanReadableErrorType::Default, color)
Mark Rousskova06baa52019-12-22 22:42:041771 }
Philipp Hanschc04a2cc2019-05-31 19:15:591772 Some("human-annotate-rs") => {
Esteban Küberae696f82024-08-08 01:46:161773 ErrorOutputType::HumanReadable(HumanReadableErrorType::AnnotateSnippet, color)
Mark Rousskova06baa52019-12-22 22:42:041774 }
Esteban Küberae696f82024-08-08 01:46:161775 Some("json") => {
1776 ErrorOutputType::Json { pretty: false, json_rendered, color_config: json_color }
1777 }
1778 Some("pretty-json") => {
1779 ErrorOutputType::Json { pretty: true, json_rendered, color_config: json_color }
1780 }
1781 Some("short") => ErrorOutputType::HumanReadable(HumanReadableErrorType::Short, color),
Esteban Küber1d780042024-06-17 15:14:071782 Some("human-unicode") => {
1783 ErrorOutputType::HumanReadable(HumanReadableErrorType::Unicode, color)
1784 }
许杰友 Jieyou Xu (Joe)cef812b2023-06-22 21:56:091785 Some(arg) => {
Nicholas Nethercoted58e3722023-12-17 23:57:261786 early_dcx.abort_if_error_and_set_error_format(ErrorOutputType::HumanReadable(
Esteban Küberae696f82024-08-08 01:46:161787 HumanReadableErrorType::Default,
1788 color,
许杰友 Jieyou Xu (Joe)cef812b2023-06-22 21:56:091789 ));
Nicholas Nethercote3a1b8e62023-12-20 03:53:501790 early_dcx.early_fatal(format!(
León Orell Valerian Liehracf63442024-11-10 16:51:371791 "argument for `--error-format` must be `human`, `human-annotate-rs`, \
1792 `human-unicode`, `json`, `pretty-json` or `short` (instead was `{arg}`)"
许杰友 Jieyou Xu (Joe)cef812b2023-06-22 21:56:091793 ))
1794 }
Nick Cameronfd46c782015-12-31 03:50:061795 }
1796 } else {
Esteban Küberae696f82024-08-08 01:46:161797 ErrorOutputType::HumanReadable(HumanReadableErrorType::Default, color)
Nick Cameronfd46c782015-12-31 03:50:061798 };
1799
Alex Crichton17312332019-07-17 19:52:561800 match error_format {
1801 ErrorOutputType::Json { .. } => {}
1802
1803 // Conservatively require that the `--json` argument is coupled with
1804 // `--error-format=json`. This means that `--json` is specified we
1805 // should actually be emitting JSON blobs.
Matthias Krüger9523c892020-02-28 13:20:331806 _ if !matches.opt_strs("json").is_empty() => {
Nicholas Nethercote3a1b8e62023-12-20 03:53:501807 early_dcx.early_fatal("using `--json` requires also using `--error-format=json`");
Alex Crichton17312332019-07-17 19:52:561808 }
1809
1810 _ => {}
1811 }
1812
Matthias Krügerad00e912020-03-20 14:03:111813 error_format
Alex Crichton17312332019-07-17 19:52:561814}
1815
Nicholas Nethercoted58e3722023-12-17 23:57:261816pub fn parse_crate_edition(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> Edition {
Alex Crichton17312332019-07-17 19:52:561817 let edition = match matches.opt_str("edition") {
Mark Rousskova06baa52019-12-22 22:42:041818 Some(arg) => Edition::from_str(&arg).unwrap_or_else(|_| {
Nicholas Nethercote3a1b8e62023-12-20 03:53:501819 early_dcx.early_fatal(format!(
许杰友 Jieyou Xu (Joe)cef812b2023-06-22 21:56:091820 "argument for `--edition` must be one of: \
Jubilee Youngde66e082022-03-25 05:11:051821 {EDITION_NAME_LIST}. (instead was `{arg}`)"
许杰友 Jieyou Xu (Joe)cef812b2023-06-22 21:56:091822 ))
Mark Rousskova06baa52019-12-22 22:42:041823 }),
Alex Crichton17312332019-07-17 19:52:561824 None => DEFAULT_EDITION,
1825 };
1826
Mara Bos3d9d0e92020-12-24 15:48:411827 if !edition.is_stable() && !nightly_options::is_unstable_enabled(matches) {
Kornel40af0862021-04-10 10:46:361828 let is_nightly = nightly_options::match_is_nightly_build(matches);
1829 let msg = if !is_nightly {
1830 format!(
Matthias Krüger23815462023-07-25 20:00:131831 "the crate requires edition {edition}, but the latest edition supported by this Rust version is {LATEST_STABLE_EDITION}"
Kornel40af0862021-04-10 10:46:361832 )
1833 } else {
Jubilee Youngde66e082022-03-25 05:11:051834 format!("edition {edition} is unstable and only available with -Z unstable-options")
Kornel40af0862021-04-10 10:46:361835 };
Nicholas Nethercote3a1b8e62023-12-20 03:53:501836 early_dcx.early_fatal(msg)
Alex Crichton17312332019-07-17 19:52:561837 }
1838
Mazdak Farrokhzad9d766ed2019-10-11 21:30:581839 edition
1840}
Alex Crichton17312332019-07-17 19:52:561841
Joshua Nelson3c9765c2022-07-06 12:44:471842fn check_error_format_stability(
klensyaa355302024-03-28 08:30:491843 early_dcx: &EarlyDiagCtxt,
Joshua Nelson3c9765c2022-07-06 12:44:471844 unstable_opts: &UnstableOptions,
León Orell Valerian Liehracf63442024-11-10 16:51:371845 format: ErrorOutputType,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:581846) {
León Orell Valerian Liehracf63442024-11-10 16:51:371847 if unstable_opts.unstable_options {
1848 return;
Oliver Schneiderc7cb2cf2017-11-03 12:38:261849 }
León Orell Valerian Liehracf63442024-11-10 16:51:371850 let format = match format {
1851 ErrorOutputType::Json { pretty: true, .. } => "pretty-json",
1852 ErrorOutputType::HumanReadable(format, _) => match format {
1853 HumanReadableErrorType::AnnotateSnippet => "human-annotate-rs",
1854 HumanReadableErrorType::Unicode => "human-unicode",
1855 _ => return,
1856 },
1857 _ => return,
1858 };
1859 early_dcx.early_fatal(format!("`--error-format={format}` is unstable"))
Mazdak Farrokhzad9d766ed2019-10-11 21:30:581860}
Oliver Schneiderc7cb2cf2017-11-03 12:38:261861
Mazdak Farrokhzad9d766ed2019-10-11 21:30:581862fn parse_output_types(
Nicholas Nethercoted58e3722023-12-17 23:57:261863 early_dcx: &EarlyDiagCtxt,
Joshua Nelson3c9765c2022-07-06 12:44:471864 unstable_opts: &UnstableOptions,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:581865 matches: &getopts::Matches,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:581866) -> OutputTypes {
Michael Woerister32414312016-08-02 20:53:581867 let mut output_types = BTreeMap::new();
Nicholas Nethercote76adf052024-11-28 19:05:561868 if !unstable_opts.parse_crate_root_only {
Alex Crichton8c963c02015-09-30 17:08:371869 for list in matches.opt_strs("emit") {
1870 for output_type in list.split(',') {
David Tolnayf72bdb12023-07-17 00:58:461871 let (shorthand, path) = split_out_file_name(output_type);
Mark Rousskova06baa52019-12-22 22:42:041872 let output_type = OutputType::from_shorthand(shorthand).unwrap_or_else(|| {
Nicholas Nethercote3a1b8e62023-12-20 03:53:501873 early_dcx.early_fatal(format!(
许杰友 Jieyou Xu (Joe)cef812b2023-06-22 21:56:091874 "unknown emission type: `{shorthand}` - expected one of: {display}",
1875 display = OutputType::shorthands_display(),
1876 ))
Mark Rousskova06baa52019-12-22 22:42:041877 });
Augie Fackleraa918712024-01-19 19:42:431878 if output_type == OutputType::ThinLinkBitcode && !unstable_opts.unstable_options {
1879 early_dcx.early_fatal(format!(
1880 "{} requested but -Zunstable-options not specified",
1881 OutputType::ThinLinkBitcode.shorthand()
1882 ));
1883 }
Alex Crichton8c963c02015-09-30 17:08:371884 output_types.insert(output_type, path);
Nick Cameron37ca3672014-05-06 11:38:011885 }
1886 }
1887 };
Michael Kohl9873acc2017-05-28 06:49:141888 if output_types.is_empty() {
Alex Crichton8c963c02015-09-30 17:08:371889 output_types.insert(OutputType::Exe, None);
Nick Cameron37ca3672014-05-06 11:38:011890 }
Mazdak Farrokhzad9d766ed2019-10-11 21:30:581891 OutputTypes(output_types)
1892}
Nick Cameron37ca3672014-05-06 11:38:011893
David Tolnayf72bdb12023-07-17 00:58:461894fn split_out_file_name(arg: &str) -> (&str, Option<OutFileName>) {
1895 match arg.split_once('=') {
1896 None => (arg, None),
1897 Some((kind, "-")) => (kind, Some(OutFileName::Stdout)),
1898 Some((kind, path)) => (kind, Some(OutFileName::Real(PathBuf::from(path)))),
1899 }
1900}
1901
Mazdak Farrokhzad9d766ed2019-10-11 21:30:581902fn should_override_cgus_and_disable_thinlto(
Nicholas Nethercoted58e3722023-12-17 23:57:261903 early_dcx: &EarlyDiagCtxt,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:581904 output_types: &OutputTypes,
1905 matches: &getopts::Matches,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:581906 mut codegen_units: Option<usize>,
1907) -> (bool, Option<usize>) {
Wesley Wiser7c6345d2022-10-27 00:28:251908 let mut disable_local_thinlto = false;
Alexander Regueiroc1d29ee2019-09-06 02:57:441909 // Issue #30063: if user requests LLVM-related output to one
Felix S. Klock IIf90c21a2015-12-04 18:35:161910 // particular path, disable codegen-units.
Mark Rousskova06baa52019-12-22 22:42:041911 let incompatible: Vec<_> = output_types
1912 .0
Santiago Pastorino52a47d42018-03-06 05:29:031913 .iter()
Alex Crichton9e35b792017-09-25 19:26:251914 .map(|ot_path| ot_path.0)
Santiago Pastorino52a47d42018-03-06 05:29:031915 .filter(|ot| !ot.is_compatible_with_codegen_units_and_single_output_file())
Alex Crichton9e35b792017-09-25 19:26:251916 .map(|ot| ot.shorthand())
1917 .collect();
1918 if !incompatible.is_empty() {
1919 match codegen_units {
1920 Some(n) if n > 1 => {
1921 if matches.opt_present("o") {
1922 for ot in &incompatible {
Nicholas Nethercoted58e3722023-12-17 23:57:261923 early_dcx.early_warn(format!(
许杰友 Jieyou Xu (Joe)cef812b2023-06-22 21:56:091924 "`--emit={ot}` with `-o` incompatible with \
Alexander Regueiro022d9c82019-09-01 17:09:591925 `-C codegen-units=N` for N > 1",
许杰友 Jieyou Xu (Joe)cef812b2023-06-22 21:56:091926 ));
Alex Crichton9e35b792017-09-25 19:26:251927 }
Nicholas Nethercoted58e3722023-12-17 23:57:261928 early_dcx.early_warn("resetting to default -C codegen-units=1");
Alex Crichton9e35b792017-09-25 19:26:251929 codegen_units = Some(1);
Wesley Wiser7c6345d2022-10-27 00:28:251930 disable_local_thinlto = true;
Alex Crichton9e35b792017-09-25 19:26:251931 }
Felix S. Klock IIf90c21a2015-12-04 18:35:161932 }
Alex Crichton855f6d12017-11-25 19:13:581933 _ => {
1934 codegen_units = Some(1);
Wesley Wiser7c6345d2022-10-27 00:28:251935 disable_local_thinlto = true;
Alex Crichton855f6d12017-11-25 19:13:581936 }
Felix S. Klock IIf90c21a2015-12-04 18:35:161937 }
1938 }
1939
Mazdak Farrokhzad9d766ed2019-10-11 21:30:581940 if codegen_units == Some(0) {
Nicholas Nethercote3a1b8e62023-12-20 03:53:501941 early_dcx.early_fatal("value for codegen units must be a positive non-zero integer");
Mazdak Farrokhzad9d766ed2019-10-11 21:30:581942 }
1943
Wesley Wiser7c6345d2022-10-27 00:28:251944 (disable_local_thinlto, codegen_units)
Mazdak Farrokhzad9d766ed2019-10-11 21:30:581945}
1946
Mazdak Farrokhzad9d766ed2019-10-11 21:30:581947fn collect_print_requests(
Nicholas Nethercoted58e3722023-12-17 23:57:261948 early_dcx: &EarlyDiagCtxt,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:581949 cg: &mut CodegenOptions,
klensyb6cfe712024-03-28 08:03:481950 unstable_opts: &UnstableOptions,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:581951 matches: &getopts::Matches,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:581952) -> Vec<PrintRequest> {
Cameron Harte1efa322016-07-10 14:22:131953 let mut prints = Vec::<PrintRequest>::new();
Maybe Wafflefb0f74a2023-05-24 14:19:221954 if cg.target_cpu.as_ref().is_some_and(|s| s == "help") {
David Tolnayc0dc0c62023-07-17 00:20:281955 prints.push(PrintRequest { kind: PrintKind::TargetCPUs, out: OutFileName::Stdout });
Cameron Harte1efa322016-07-10 14:22:131956 cg.target_cpu = None;
1957 };
1958 if cg.target_feature == "help" {
David Tolnayc0dc0c62023-07-17 00:20:281959 prints.push(PrintRequest { kind: PrintKind::TargetFeatures, out: OutFileName::Stdout });
Matthias Krügerede1f7d2018-08-23 08:14:521960 cg.target_feature = String::new();
Cameron Harte1efa322016-07-10 14:22:131961 }
Cameron Harte1efa322016-07-10 14:22:131962
David Tolnayc0dc0c62023-07-17 00:20:281963 const PRINT_KINDS: &[(&str, PrintKind)] = &[
Nicholas Nethercote20046ce2023-11-29 05:33:081964 // tidy-alphabetical-start
1965 ("all-target-specs-json", PrintKind::AllTargetSpecs),
David Tolnayc0dc0c62023-07-17 00:20:281966 ("calling-conventions", PrintKind::CallingConventions),
Nicholas Nethercote20046ce2023-11-29 05:33:081967 ("cfg", PrintKind::Cfg),
Urgauac59bdc2024-04-22 21:47:481968 ("check-cfg", PrintKind::CheckCfg),
Nicholas Nethercote20046ce2023-11-29 05:33:081969 ("code-models", PrintKind::CodeModels),
1970 ("crate-name", PrintKind::CrateName),
1971 ("deployment-target", PrintKind::DeploymentTarget),
1972 ("file-names", PrintKind::FileNames),
Noratriebba481512024-10-17 17:03:061973 ("host-tuple", PrintKind::HostTuple),
Nicholas Nethercote20046ce2023-11-29 05:33:081974 ("link-args", PrintKind::LinkArgs),
1975 ("native-static-libs", PrintKind::NativeStaticLibs),
1976 ("relocation-models", PrintKind::RelocationModels),
1977 ("split-debuginfo", PrintKind::SplitDebuginfo),
1978 ("stack-protector-strategies", PrintKind::StackProtectorStrategies),
1979 ("sysroot", PrintKind::Sysroot),
David Tolnayc0dc0c62023-07-17 00:20:281980 ("target-cpus", PrintKind::TargetCPUs),
1981 ("target-features", PrintKind::TargetFeatures),
Nicholas Nethercote20046ce2023-11-29 05:33:081982 ("target-libdir", PrintKind::TargetLibdir),
1983 ("target-list", PrintKind::TargetList),
David Tolnayc0dc0c62023-07-17 00:20:281984 ("target-spec-json", PrintKind::TargetSpec),
Nicholas Nethercote20046ce2023-11-29 05:33:081985 ("tls-models", PrintKind::TlsModels),
1986 // tidy-alphabetical-end
nilsb20d9692022-11-01 15:24:011987 ];
1988
David Tolnay32cac2e2023-07-17 02:06:041989 // We disallow reusing the same path in multiple prints, such as `--print
1990 // cfg=output.txt --print link-args=output.txt`, because outputs are printed
1991 // by disparate pieces of the compiler, and keeping track of which files
1992 // need to be overwritten vs appended to is annoying.
1993 let mut printed_paths = FxHashSet::default();
1994
nilsb20d9692022-11-01 15:24:011995 prints.extend(matches.opt_strs("print").into_iter().map(|req| {
David Tolnayf72bdb12023-07-17 00:58:461996 let (req, out) = split_out_file_name(&req);
1997
David Tolnayc0dc0c62023-07-17 00:20:281998 let kind = match PRINT_KINDS.iter().find(|&&(name, _)| name == req) {
1999 Some((_, PrintKind::TargetSpec)) => {
nilsb20d9692022-11-01 15:24:012000 if unstable_opts.unstable_options {
David Tolnayc0dc0c62023-07-17 00:20:282001 PrintKind::TargetSpec
nilsb20d9692022-11-01 15:24:012002 } else {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502003 early_dcx.early_fatal(
nilsb20d9692022-11-01 15:24:012004 "the `-Z unstable-options` flag must also be passed to \
Pietro Albinief2bf6d2023-03-09 13:52:452005 enable the target-spec-json print option",
2006 );
2007 }
2008 }
David Tolnayc0dc0c62023-07-17 00:20:282009 Some((_, PrintKind::AllTargetSpecs)) => {
Pietro Albinief2bf6d2023-03-09 13:52:452010 if unstable_opts.unstable_options {
David Tolnayc0dc0c62023-07-17 00:20:282011 PrintKind::AllTargetSpecs
Pietro Albinief2bf6d2023-03-09 13:52:452012 } else {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502013 early_dcx.early_fatal(
Pietro Albinief2bf6d2023-03-09 13:52:452014 "the `-Z unstable-options` flag must also be passed to \
2015 enable the all-target-specs-json print option",
nilsb20d9692022-11-01 15:24:012016 );
2017 }
2018 }
Urgauac59bdc2024-04-22 21:47:482019 Some((_, PrintKind::CheckCfg)) => {
2020 if unstable_opts.unstable_options {
2021 PrintKind::CheckCfg
2022 } else {
2023 early_dcx.early_fatal(
2024 "the `-Z unstable-options` flag must also be passed to \
2025 enable the check-cfg print option",
2026 );
2027 }
2028 }
David Tolnayc0dc0c62023-07-17 00:20:282029 Some(&(_, print_kind)) => print_kind,
nilsb20d9692022-11-01 15:24:012030 None => {
2031 let prints =
David Tolnayc0dc0c62023-07-17 00:20:282032 PRINT_KINDS.iter().map(|(name, _)| format!("`{name}`")).collect::<Vec<_>>();
nilsb20d9692022-11-01 15:24:012033 let prints = prints.join(", ");
Urgau153b1f02024-04-24 13:34:572034
2035 let mut diag =
2036 early_dcx.early_struct_fatal(format!("unknown print request: `{req}`"));
2037 #[allow(rustc::diagnostic_outside_of_impl)]
2038 diag.help(format!("valid print requests are: {prints}"));
2039 diag.emit()
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582040 }
David Tolnayc0dc0c62023-07-17 00:20:282041 };
David Tolnayf72bdb12023-07-17 00:58:462042
2043 let out = out.unwrap_or(OutFileName::Stdout);
David Tolnay32cac2e2023-07-17 02:06:042044 if let OutFileName::Real(path) = &out {
2045 if !printed_paths.insert(path.clone()) {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502046 early_dcx.early_fatal(format!(
David Tolnay32cac2e2023-07-17 02:06:042047 "cannot print multiple outputs to the same path: {}",
2048 path.display(),
2049 ));
2050 }
2051 }
2052
David Tolnayf72bdb12023-07-17 00:58:462053 PrintRequest { kind, out }
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582054 }));
Alex Crichton117984b2014-12-16 00:03:392055
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582056 prints
2057}
2058
Noratrieba26450c2024-10-17 17:02:322059pub fn parse_target_triple(early_dcx: &EarlyDiagCtxt, matches: &getopts::Matches) -> TargetTuple {
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582060 match matches.opt_str("target") {
2061 Some(target) if target.ends_with(".json") => {
Philipp Oppermann7b491902018-03-24 19:14:592062 let path = Path::new(&target);
Noratrieba26450c2024-10-17 17:02:322063 TargetTuple::from_path(path).unwrap_or_else(|_| {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502064 early_dcx.early_fatal(format!("target file {path:?} does not exist"))
Mark Rousskova06baa52019-12-22 22:42:042065 })
Philipp Oppermann3908b2e2018-03-14 14:27:062066 }
Noratrieba26450c2024-10-17 17:02:322067 Some(target) => TargetTuple::TargetTuple(target),
2068 _ => TargetTuple::from_tuple(host_tuple()),
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582069 }
2070}
2071
2072fn parse_opt_level(
Nicholas Nethercoted58e3722023-12-17 23:57:262073 early_dcx: &EarlyDiagCtxt,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582074 matches: &getopts::Matches,
2075 cg: &CodegenOptions,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582076) -> OptLevel {
2077 // The `-O` and `-C opt-level` flags specify the same setting, so we want to be able
2078 // to use them interchangeably. However, because they're technically different flags,
2079 // we need to work out manually which should take precedence if both are supplied (i.e.
2080 // the rightmost flag). We do this by finding the (rightmost) position of both flags and
2081 // comparing them. Note that if a flag is not found, its position will be `None`, which
2082 // always compared less than `Some(_)`.
2083 let max_o = matches.opt_positions("O").into_iter().max();
Mark Rousskova06baa52019-12-22 22:42:042084 let max_c = matches
2085 .opt_strs_pos("C")
2086 .into_iter()
Eric Arellano12db2222020-12-07 18:59:242087 .flat_map(|(i, s)| {
2088 // NB: This can match a string without `=`.
Matthias Krügerde598442022-12-14 23:06:342089 if let Some("opt-level") = s.split('=').next() { Some(i) } else { None }
Eric Arellano12db2222020-12-07 18:59:242090 })
Mark Rousskova06baa52019-12-22 22:42:042091 .max();
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582092 if max_o > max_c {
2093 OptLevel::Default
Philipp Oppermann3908b2e2018-03-14 14:27:062094 } else {
Nicholas Nethercote58217bc2020-04-02 05:44:472095 match cg.opt_level.as_ref() {
2096 "0" => OptLevel::No,
2097 "1" => OptLevel::Less,
2098 "2" => OptLevel::Default,
2099 "3" => OptLevel::Aggressive,
2100 "s" => OptLevel::Size,
2101 "z" => OptLevel::SizeMin,
2102 arg => {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502103 early_dcx.early_fatal(format!(
许杰友 Jieyou Xu (Joe)cef812b2023-06-22 21:56:092104 "optimization level needs to be \
Jubilee Youngde66e082022-03-25 05:11:052105 between 0-3, s or z (instead was `{arg}`)"
许杰友 Jieyou Xu (Joe)cef812b2023-06-22 21:56:092106 ));
Alex Crichton117984b2014-12-16 00:03:392107 }
Nick Cameron37ca3672014-05-06 11:38:012108 }
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582109 }
2110}
2111
Julia Tatz0504a332021-04-06 20:00:352112fn select_debuginfo(matches: &getopts::Matches, cg: &CodegenOptions) -> DebugInfo {
varkore8e43c92019-04-30 20:52:052113 let max_g = matches.opt_positions("g").into_iter().max();
Mark Rousskova06baa52019-12-22 22:42:042114 let max_c = matches
2115 .opt_strs_pos("C")
2116 .into_iter()
Eric Arellano12db2222020-12-07 18:59:242117 .flat_map(|(i, s)| {
2118 // NB: This can match a string without `=`.
Matthias Krügerde598442022-12-14 23:06:342119 if let Some("debuginfo") = s.split('=').next() { Some(i) } else { None }
Eric Arellano12db2222020-12-07 18:59:242120 })
Mark Rousskova06baa52019-12-22 22:42:042121 .max();
Julia Tatz0504a332021-04-06 20:00:352122 if max_g > max_c { DebugInfo::Full } else { cg.debuginfo }
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582123}
Nick Cameron37ca3672014-05-06 11:38:012124
Nicholas Nethercote5f11d192023-11-28 05:30:572125fn parse_assert_incr_state(
Nicholas Nethercoted58e3722023-12-17 23:57:262126 early_dcx: &EarlyDiagCtxt,
pierwill1642fdf2021-10-31 22:05:482127 opt_assertion: &Option<String>,
pierwill1642fdf2021-10-31 22:05:482128) -> Option<IncrementalStateAssertion> {
2129 match opt_assertion {
2130 Some(s) if s.as_str() == "loaded" => Some(IncrementalStateAssertion::Loaded),
2131 Some(s) if s.as_str() == "not-loaded" => Some(IncrementalStateAssertion::NotLoaded),
Jubilee Youngde66e082022-03-25 05:11:052132 Some(s) => {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502133 early_dcx.early_fatal(format!("unexpected incremental state assertion value: {s}"))
Jubilee Youngde66e082022-03-25 05:11:052134 }
pierwill1642fdf2021-10-31 22:05:482135 None => None,
2136 }
2137}
2138
Eric Huss590dd7d2019-12-05 22:43:532139pub fn parse_externs(
Nicholas Nethercoted58e3722023-12-17 23:57:262140 early_dcx: &EarlyDiagCtxt,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582141 matches: &getopts::Matches,
Joshua Nelson3c9765c2022-07-06 12:44:472142 unstable_opts: &UnstableOptions,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582143) -> Externs {
Nicholas Nethercotedba94162023-11-28 14:16:252144 fn is_ascii_ident(string: &str) -> bool {
2145 let mut chars = string.chars();
2146 if let Some(start) = chars.next()
2147 && (start.is_ascii_alphabetic() || start == '_')
2148 {
2149 chars.all(|char| char.is_ascii_alphanumeric() || char == '_')
2150 } else {
2151 false
2152 }
2153 }
2154
Joshua Nelson3c9765c2022-07-06 12:44:472155 let is_unstable_enabled = unstable_opts.unstable_options;
Aaron Hill482b77a2019-04-07 22:48:402156 let mut externs: BTreeMap<String, ExternEntry> = BTreeMap::new();
Eric Huss590dd7d2019-12-05 22:43:532157 for arg in matches.opt_strs("extern") {
Eric Arellano12db2222020-12-07 18:59:242158 let (name, path) = match arg.split_once('=') {
2159 None => (arg, None),
Ryan Levick6c7ecd02021-01-26 21:27:422160 Some((name, path)) => (name.to_string(), Some(Path::new(path))),
Eric Arellano12db2222020-12-07 18:59:242161 };
2162 let (options, name) = match name.split_once(':') {
2163 None => (None, name),
2164 Some((opts, name)) => (Some(opts), name.to_string()),
Eric Huss590dd7d2019-12-05 22:43:532165 };
Alex Crichtoncc3c8bb2014-07-01 15:37:542166
Nicholas Nethercotedba94162023-11-28 14:16:252167 if !is_ascii_ident(&name) {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502168 let mut error = early_dcx.early_struct_fatal(format!(
León Orell Valerian Liehr8d81d5a2023-08-18 11:23:532169 "crate name `{name}` passed to `--extern` is not a valid ASCII identifier"
2170 ));
Nicholas Nethercote1b3733e2023-11-06 02:06:402171 let adjusted_name = name.replace('-', "_");
Nicholas Nethercotedba94162023-11-28 14:16:252172 if is_ascii_ident(&adjusted_name) {
Nicholas Nethercoteb7d58ee2024-02-20 03:12:502173 #[allow(rustc::diagnostic_outside_of_impl)] // FIXME
León Orell Valerian Liehr8d81d5a2023-08-18 11:23:532174 error.help(format!(
2175 "consider replacing the dashes with underscores: `{adjusted_name}`"
2176 ));
2177 }
2178 error.emit();
2179 }
2180
Ryan Levick6c7ecd02021-01-26 21:27:422181 let path = path.map(|p| CanonicalizedPath::new(p));
2182
Eric Huss590dd7d2019-12-05 22:43:532183 let entry = externs.entry(name.to_owned());
Aaron Hill482b77a2019-04-07 22:48:402184
Eric Huss590dd7d2019-12-05 22:43:532185 use std::collections::btree_map::Entry;
Aaron Hill4dfce342019-04-09 21:24:242186
Eric Huss590dd7d2019-12-05 22:43:532187 let entry = if let Some(path) = path {
2188 // --extern prelude_name=some_file.rlib
2189 match entry {
2190 Entry::Vacant(vacant) => {
2191 let files = BTreeSet::from_iter(iter::once(path));
2192 vacant.insert(ExternEntry::new(ExternLocation::ExactPaths(files)))
2193 }
2194 Entry::Occupied(occupied) => {
2195 let ext_ent = occupied.into_mut();
2196 match ext_ent {
2197 ExternEntry { location: ExternLocation::ExactPaths(files), .. } => {
2198 files.insert(path);
2199 }
2200 ExternEntry {
2201 location: location @ ExternLocation::FoundInLibrarySearchDirectories,
2202 ..
2203 } => {
2204 // Exact paths take precedence over search directories.
2205 let files = BTreeSet::from_iter(iter::once(path));
2206 *location = ExternLocation::ExactPaths(files);
2207 }
2208 }
2209 ext_ent
2210 }
2211 }
2212 } else {
2213 // --extern prelude_name
2214 match entry {
2215 Entry::Vacant(vacant) => {
2216 vacant.insert(ExternEntry::new(ExternLocation::FoundInLibrarySearchDirectories))
2217 }
2218 Entry::Occupied(occupied) => {
2219 // Ignore if already specified.
2220 occupied.into_mut()
2221 }
2222 }
2223 };
2224
2225 let mut is_private_dep = false;
2226 let mut add_prelude = true;
Jeremy Fitzhardinge9102edf2022-04-14 22:09:002227 let mut nounused_dep = false;
Matt Hammerly812f2d72023-03-14 03:55:432228 let mut force = false;
Eric Huss590dd7d2019-12-05 22:43:532229 if let Some(opts) = options {
2230 if !is_unstable_enabled {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502231 early_dcx.early_fatal(
Eric Huss590dd7d2019-12-05 22:43:532232 "the `-Z unstable-options` flag must also be passed to \
est31ef658902023-03-03 07:38:072233 enable `--extern` options",
Eric Huss590dd7d2019-12-05 22:43:532234 );
2235 }
2236 for opt in opts.split(',') {
2237 match opt {
2238 "priv" => is_private_dep = true,
2239 "noprelude" => {
2240 if let ExternLocation::ExactPaths(_) = &entry.location {
2241 add_prelude = false;
2242 } else {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502243 early_dcx.early_fatal(
Eric Huss590dd7d2019-12-05 22:43:532244 "the `noprelude` --extern option requires a file path",
2245 );
2246 }
2247 }
Jeremy Fitzhardinge9102edf2022-04-14 22:09:002248 "nounused" => nounused_dep = true,
Matt Hammerly812f2d72023-03-14 03:55:432249 "force" => force = true,
Nicholas Nethercote3a1b8e62023-12-20 03:53:502250 _ => early_dcx.early_fatal(format!("unknown --extern option `{opt}`")),
Eric Huss590dd7d2019-12-05 22:43:532251 }
2252 }
2253 }
2254
2255 // Crates start out being not private, and go to being private `priv`
2256 // is specified.
2257 entry.is_private_dep |= is_private_dep;
Jeremy Fitzhardinge9102edf2022-04-14 22:09:002258 // likewise `nounused`
2259 entry.nounused_dep |= nounused_dep;
Matt Hammerly812f2d72023-03-14 03:55:432260 // and `force`
2261 entry.force |= force;
Eric Huss590dd7d2019-12-05 22:43:532262 // If any flag is missing `noprelude`, then add to the prelude.
2263 entry.add_prelude |= add_prelude;
Aaron Hill482b77a2019-04-07 22:48:402264 }
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582265 Externs(externs)
2266}
Aaron Hill7cc3ce32019-03-25 03:06:322267
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582268fn parse_remap_path_prefix(
Nicholas Nethercoted58e3722023-12-17 23:57:262269 early_dcx: &EarlyDiagCtxt,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582270 matches: &getopts::Matches,
Joshua Nelson3c9765c2022-07-06 12:44:472271 unstable_opts: &UnstableOptions,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582272) -> Vec<(PathBuf, PathBuf)> {
danakjce35f8e2021-07-22 18:52:452273 let mut mapping: Vec<(PathBuf, PathBuf)> = matches
Santiago Pastorino52a47d42018-03-06 05:29:032274 .opt_strs("remap-path-prefix")
Jeremy Fitzhardinge56a68282018-02-18 23:05:242275 .into_iter()
Eric Arellano12db2222020-12-07 18:59:242276 .map(|remap| match remap.rsplit_once('=') {
Nicholas Nethercotef6aa4182023-12-18 00:15:132277 None => {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502278 early_dcx.early_fatal("--remap-path-prefix must contain '=' between FROM and TO")
Nicholas Nethercotef6aa4182023-12-18 00:15:132279 }
Eric Arellano12db2222020-12-07 18:59:242280 Some((from, to)) => (PathBuf::from(from), PathBuf::from(to)),
Jeremy Fitzhardinge56a68282018-02-18 23:05:242281 })
danakjce35f8e2021-07-22 18:52:452282 .collect();
Joshua Nelson3c9765c2022-07-06 12:44:472283 match &unstable_opts.remap_cwd_prefix {
danakjce35f8e2021-07-22 18:52:452284 Some(to) => match std::env::current_dir() {
2285 Ok(cwd) => mapping.push((cwd, to.clone())),
2286 Err(_) => (),
2287 },
2288 None => (),
2289 };
2290 mapping
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582291}
Jeremy Fitzhardinge56a68282018-02-18 23:05:242292
Guillaume Gomez486e55e2023-11-27 12:47:262293fn parse_logical_env(
klensyaa355302024-03-28 08:30:492294 early_dcx: &EarlyDiagCtxt,
Guillaume Gomez486e55e2023-11-27 12:47:262295 matches: &getopts::Matches,
2296) -> FxIndexMap<String, String> {
2297 let mut vars = FxIndexMap::default();
2298
Guillaume Gomez462bcac2024-01-12 10:02:572299 for arg in matches.opt_strs("env-set") {
Guillaume Gomez486e55e2023-11-27 12:47:262300 if let Some((name, val)) = arg.split_once('=') {
2301 vars.insert(name.to_string(), val.to_string());
2302 } else {
Guillaume Gomez462bcac2024-01-12 10:02:572303 early_dcx.early_fatal(format!("`--env-set`: specify value for variable `{arg}`"));
Guillaume Gomez486e55e2023-11-27 12:47:262304 }
2305 }
2306
2307 vars
2308}
2309
David Wood7bab7692022-07-25 12:02:392310// JUSTIFICATION: before wrapper fn is available
Mark Rousskov154a09d2022-08-09 13:56:132311#[allow(rustc::bad_opt_access)]
Nicholas Nethercoted58e3722023-12-17 23:57:262312pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::Matches) -> Options {
2313 let color = parse_color(early_dcx, matches);
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582314
Nicholas Nethercoted58e3722023-12-17 23:57:262315 let edition = parse_crate_edition(early_dcx, matches);
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582316
Aaron Hill63523e42021-12-04 19:34:202317 let JsonConfig {
2318 json_rendered,
Esteban Küberae696f82024-08-08 01:46:162319 json_color,
Aaron Hill63523e42021-12-04 19:34:202320 json_artifact_notifications,
2321 json_unused_externs,
2322 json_future_incompat,
Nicholas Nethercoted58e3722023-12-17 23:57:262323 } = parse_json(early_dcx, matches);
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582324
Esteban Küberae696f82024-08-08 01:46:162325 let error_format = parse_error_format(early_dcx, matches, color, json_color, json_rendered);
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582326
Nicholas Nethercoted58e3722023-12-17 23:57:262327 early_dcx.abort_if_error_and_set_error_format(error_format);
许杰友 Jieyou Xu (Joe)53245a12023-06-28 15:51:122328
David Wood44c1fcc2022-07-06 10:57:412329 let diagnostic_width = matches.opt_get("diagnostic-width").unwrap_or_else(|_| {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502330 early_dcx.early_fatal("`--diagnostic-width` must be an positive integer");
David Woode5288842022-02-14 06:01:382331 });
2332
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582333 let unparsed_crate_types = matches.opt_strs("crate-type");
2334 let crate_types = parse_crate_types_from_list(unparsed_crate_types)
Nicholas Nethercote3a1b8e62023-12-20 03:53:502335 .unwrap_or_else(|e| early_dcx.early_fatal(e));
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582336
Nicholas Nethercoted58e3722023-12-17 23:57:262337 let mut unstable_opts = UnstableOptions::build(early_dcx, matches);
2338 let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(early_dcx, matches);
Ryan Levick3b206b72021-06-02 15:09:072339
Nicholas Nethercote88432232024-01-05 03:11:122340 check_error_format_stability(early_dcx, &unstable_opts, error_format);
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582341
Nicholas Nethercoted58e3722023-12-17 23:57:262342 let output_types = parse_output_types(early_dcx, &unstable_opts, matches);
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582343
Nicholas Nethercoted58e3722023-12-17 23:57:262344 let mut cg = CodegenOptions::build(early_dcx, matches);
Zalatharce3e14a2024-10-17 09:11:202345 let (disable_local_thinlto, codegen_units) = should_override_cgus_and_disable_thinlto(
Nicholas Nethercotef6aa4182023-12-18 00:15:132346 early_dcx,
2347 &output_types,
2348 matches,
2349 cg.codegen_units,
2350 );
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582351
Tomasz Miąskoa73d1bf2023-11-29 00:00:002352 if unstable_opts.threads == 0 {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502353 early_dcx.early_fatal("value for threads must be a positive non-zero integer");
Tomasz Miąskoa73d1bf2023-11-29 00:00:002354 }
2355
Michal Piotrowski7591eb62024-10-30 11:31:262356 if unstable_opts.threads == parse::MAX_THREADS_CAP {
2357 early_dcx.early_warn(format!("number of threads was capped at {}", parse::MAX_THREADS_CAP));
2358 }
2359
Matthias Krüger08f29042020-03-29 18:19:142360 let incremental = cg.incremental.as_ref().map(PathBuf::from);
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582361
Nicholas Nethercoted58e3722023-12-17 23:57:262362 let assert_incr_state = parse_assert_incr_state(early_dcx, &unstable_opts.assert_incr_state);
pierwill1642fdf2021-10-31 22:05:482363
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582364 if cg.profile_generate.enabled() && cg.profile_use.is_some() {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502365 early_dcx.early_fatal("options `-C profile-generate` and `-C profile-use` are exclusive");
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582366 }
2367
Joshua Nelson3c9765c2022-07-06 12:44:472368 if unstable_opts.profile_sample_use.is_some()
Michael Benfielda17193d2021-05-07 07:41:372369 && (cg.profile_generate.enabled() || cg.profile_use.is_some())
2370 {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502371 early_dcx.early_fatal(
Michael Benfielda17193d2021-05-07 07:41:372372 "option `-Z profile-sample-use` cannot be used with `-C profile-generate` or `-C profile-use`",
2373 );
2374 }
2375
Zalathar76103a82023-11-02 06:34:052376 // Check for unstable values of `-C symbol-mangling-version`.
2377 // This is what prevents them from being used on stable compilers.
2378 match cg.symbol_mangling_version {
2379 // Stable values:
2380 None | Some(SymbolManglingVersion::V0) => {}
h14677928226e53e662023-12-05 04:42:572381
Zalathar76103a82023-11-02 06:34:052382 // Unstable values:
2383 Some(SymbolManglingVersion::Legacy) => {
2384 if !unstable_opts.unstable_options {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502385 early_dcx.early_fatal(
Zalathar76103a82023-11-02 06:34:052386 "`-C symbol-mangling-version=legacy` requires `-Z unstable-options`",
2387 );
2388 }
Josh Triplettbbf4b662021-10-21 12:02:592389 }
h14677928226e53e662023-12-05 04:42:572390 Some(SymbolManglingVersion::Hashed) => {
2391 if !unstable_opts.unstable_options {
2392 early_dcx.early_fatal(
2393 "`-C symbol-mangling-version=hashed` requires `-Z unstable-options`",
2394 );
2395 }
2396 }
Josh Triplettbbf4b662021-10-21 12:02:592397 }
2398
Zalathar9f287dd2023-10-25 03:57:252399 if cg.instrument_coverage != InstrumentCoverage::No {
Rich Kadela6f8b8a2020-07-02 18:27:152400 if cg.profile_generate.enabled() || cg.profile_use.is_some() {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502401 early_dcx.early_fatal(
Josh Triplett34106f82021-10-21 14:04:222402 "option `-C instrument-coverage` is not compatible with either `-C profile-use` \
Rich Kadela6f8b8a2020-07-02 18:27:152403 or `-C profile-generate`",
2404 );
2405 }
2406
Josh Triplett34106f82021-10-21 14:04:222407 // `-C instrument-coverage` implies `-C symbol-mangling-version=v0` - to ensure consistent
Rich Kadelddb054a2020-08-27 19:53:432408 // and reversible name mangling. Note, LLVM coverage tools can analyze coverage over
2409 // multiple runs, including some changes to source code; so mangled names must be consistent
2410 // across compilations.
Josh Triplettbbf4b662021-10-21 12:02:592411 match cg.symbol_mangling_version {
2412 None => cg.symbol_mangling_version = Some(SymbolManglingVersion::V0),
Rich Kadel4f550f12020-12-14 08:25:292413 Some(SymbolManglingVersion::Legacy) => {
Nicholas Nethercoted58e3722023-12-17 23:57:262414 early_dcx.early_warn(
Josh Triplett34106f82021-10-21 14:04:222415 "-C instrument-coverage requires symbol mangling version `v0`, \
Josh Triplettbbf4b662021-10-21 12:02:592416 but `-C symbol-mangling-version=legacy` was specified",
Rich Kadel4f550f12020-12-14 08:25:292417 );
2418 }
2419 Some(SymbolManglingVersion::V0) => {}
h14677928226e53e662023-12-05 04:42:572420 Some(SymbolManglingVersion::Hashed) => {
2421 early_dcx.early_warn(
2422 "-C instrument-coverage requires symbol mangling version `v0`, \
2423 but `-C symbol-mangling-version=hashed` was specified",
2424 );
2425 }
Rich Kadel4f550f12020-12-14 08:25:292426 }
Rich Kadela6f8b8a2020-07-02 18:27:152427 }
2428
Rich Kadel3875abe2020-09-16 17:47:562429 if let Ok(graphviz_font) = std::env::var("RUSTC_GRAPHVIZ_FONT") {
klensyb6cfe712024-03-28 08:03:482430 // FIXME: this is only mutation of UnstableOptions here, move into
2431 // UnstableOptions::build?
Joshua Nelson3c9765c2022-07-06 12:44:472432 unstable_opts.graphviz_font = graphviz_font;
Rich Kadel3875abe2020-09-16 17:47:562433 }
2434
Alex Crichtone1832fa2020-04-30 17:53:162435 if !cg.embed_bitcode {
Nicholas Nethercoteae322ff2020-04-19 10:48:432436 match cg.lto {
2437 LtoCli::No | LtoCli::Unspecified => {}
许杰友 Jieyou Xu (Joe)cef812b2023-06-22 21:56:092438 LtoCli::Yes | LtoCli::NoParam | LtoCli::Thin | LtoCli::Fat => {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502439 early_dcx.early_fatal("options `-C embed-bitcode=no` and `-C lto` are incompatible")
许杰友 Jieyou Xu (Joe)cef812b2023-06-22 21:56:092440 }
Nicholas Nethercoteae322ff2020-04-19 10:48:432441 }
2442 }
2443
Jubilee Young7d160ae2024-05-05 00:52:472444 if !nightly_options::is_unstable_enabled(matches)
2445 && cg.force_frame_pointers == FramePointer::NonLeaf
2446 {
2447 early_dcx.early_fatal(
Jubilee Young598e2652024-05-14 19:26:012448 "`-Cforce-frame-pointers=non-leaf` or `always` also requires `-Zunstable-options` \
Jubilee Young7d160ae2024-05-05 00:52:472449 and a nightly compiler",
2450 )
2451 }
2452
Rémy Rakic38dca732023-06-21 21:49:412453 // For testing purposes, until we have more feedback about these options: ensure `-Z
Rémy Rakic71285c12023-09-20 17:00:572454 // unstable-options` is required when using the unstable `-C link-self-contained` and `-C
2455 // linker-flavor` options.
Rémy Rakic38dca732023-06-21 21:49:412456 if !nightly_options::is_unstable_enabled(matches) {
2457 let uses_unstable_self_contained_option =
2458 cg.link_self_contained.are_unstable_variants_set();
2459 if uses_unstable_self_contained_option {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502460 early_dcx.early_fatal(
Rémy Rakic38dca732023-06-21 21:49:412461 "only `-C link-self-contained` values `y`/`yes`/`on`/`n`/`no`/`off` are stable, \
2462 the `-Z unstable-options` flag must also be passed to use the unstable values",
Vadim Petrochenkov23f177d2023-05-22 21:00:352463 );
Rémy Rakic38dca732023-06-21 21:49:412464 }
2465
2466 if let Some(flavor) = cg.linker_flavor {
2467 if flavor.is_unstable() {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502468 early_dcx.early_fatal(format!(
Rémy Rakic38dca732023-06-21 21:49:412469 "the linker flavor `{}` is unstable, the `-Z unstable-options` \
2470 flag must also be passed to use the unstable values",
2471 flavor.desc()
2472 ));
2473 }
Vadim Petrochenkov23f177d2023-05-22 21:00:352474 }
2475 }
2476
Rémy Rakic13948742023-09-21 13:27:452477 // Check `-C link-self-contained` for consistency: individual components cannot be both enabled
2478 // and disabled at the same time.
2479 if let Some(erroneous_components) = cg.link_self_contained.check_consistency() {
2480 let names: String = erroneous_components
2481 .into_iter()
2482 .map(|c| c.as_str().unwrap())
2483 .intersperse(", ")
2484 .collect();
Nicholas Nethercote3a1b8e62023-12-20 03:53:502485 early_dcx.early_fatal(format!(
Rémy Rakic13948742023-09-21 13:27:452486 "some `-C link-self-contained` components were both enabled and disabled: {names}"
2487 ));
2488 }
2489
klensyb6cfe712024-03-28 08:03:482490 let prints = collect_print_requests(early_dcx, &mut cg, &unstable_opts, matches);
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582491
2492 let cg = cg;
2493
2494 let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
Nicholas Nethercoted58e3722023-12-17 23:57:262495 let target_triple = parse_target_triple(early_dcx, matches);
2496 let opt_level = parse_opt_level(early_dcx, matches, &cg);
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582497 // The `-g` and `-C debuginfo` flags specify the same setting, so we want to be able
2498 // to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`)
2499 // for more details.
2500 let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
Julia Tatz0504a332021-04-06 20:00:352501 let debuginfo = select_debuginfo(matches, &cg);
Nicholas Nethercoteb6d04932023-11-29 05:56:152502 let debuginfo_compression = unstable_opts.debuginfo_compression;
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582503
Zalathar78edefe2024-11-11 10:42:422504 let crate_name = matches.opt_str("crate-name");
2505 let unstable_features = UnstableFeatures::from_environment(crate_name.as_deref());
2506 // Parse any `-l` flags, which link to native libraries.
2507 let libs = parse_native_libs(early_dcx, &unstable_opts, unstable_features, matches);
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582508
2509 let test = matches.opt_present("test");
2510
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582511 if !cg.remark.is_empty() && debuginfo == DebugInfo::None {
Nicholas Nethercoted58e3722023-12-17 23:57:262512 early_dcx.early_warn("-C remark requires \"-C debuginfo=n\" to show source locations");
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582513 }
2514
Jakub Beránek62728c72023-06-25 21:39:022515 if cg.remark.is_empty() && unstable_opts.remark_dir.is_some() {
Nicholas Nethercotef6aa4182023-12-18 00:15:132516 early_dcx
2517 .early_warn("using -Z remark-dir without enabling remarks using e.g. -C remark=all");
Jakub Beránek62728c72023-06-25 21:39:022518 }
2519
Nicholas Nethercoted58e3722023-12-17 23:57:262520 let externs = parse_externs(early_dcx, matches, &unstable_opts);
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582521
Nicholas Nethercoted58e3722023-12-17 23:57:262522 let remap_path_prefix = parse_remap_path_prefix(early_dcx, matches, &unstable_opts);
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582523
Nicholas Nethercoted58e3722023-12-17 23:57:262524 let pretty = parse_pretty(early_dcx, &unstable_opts);
Mark Rousskovdd6df0d2019-11-04 02:42:032525
gftea2c5583e2023-01-15 17:42:042526 // query-dep-graph is required if dump-dep-graph is given #106736
2527 if unstable_opts.dump_dep_graph && !unstable_opts.query_dep_graph {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502528 early_dcx.early_fatal("can't dump dependency graph without `-Z query-dep-graph`");
gftea2c5583e2023-01-15 17:42:042529 }
2530
Nicholas Nethercoted58e3722023-12-17 23:57:262531 let logical_env = parse_logical_env(early_dcx, matches);
Guillaume Gomez486e55e2023-11-27 12:47:262532
Maybe Waffle54415232024-02-15 00:03:342533 let sysroot = filesearch::materialize_sysroot(sysroot_opt);
Lukas Wirth3d65c922024-03-06 12:28:122534
Joshua Nelson39648ea2021-04-27 16:25:122535 let real_rust_source_base_dir = {
2536 // This is the location used by the `rust-src` `rustup` component.
2537 let mut candidate = sysroot.join("lib/rustlib/src/rust");
2538 if let Ok(metadata) = candidate.symlink_metadata() {
onur-ozkan48192702024-07-06 21:07:082539 // Replace the symlink bootstrap creates, with its destination.
Joshua Nelson39648ea2021-04-27 16:25:122540 // We could try to use `fs::canonicalize` instead, but that might
2541 // produce unnecessarily verbose path.
2542 if metadata.file_type().is_symlink() {
2543 if let Ok(symlink_dest) = std::fs::read_link(&candidate) {
2544 candidate = symlink_dest;
2545 }
2546 }
2547 }
2548
2549 // Only use this directory if it has a file we can expect to always find.
Maybe Waffle5bf6a462023-02-15 17:39:432550 candidate.join("library/std/src/lib.rs").is_file().then_some(candidate)
Joshua Nelson39648ea2021-04-27 16:25:122551 };
2552
Lukas Wirth91547572024-02-29 13:16:322553 let mut search_paths = vec![];
2554 for s in &matches.opt_strs("L") {
Lukas Wirth48151552024-04-23 08:44:142555 search_paths.push(SearchPath::from_cli_opt(
2556 &sysroot,
2557 &target_triple,
2558 early_dcx,
2559 s,
2560 unstable_opts.unstable_options,
2561 ));
Lukas Wirth91547572024-02-29 13:16:322562 }
2563
Aaron Hilla8950692021-08-12 20:30:402564 let working_dir = std::env::current_dir().unwrap_or_else(|e| {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502565 early_dcx.early_fatal(format!("Current directory is invalid: {e}"));
Aaron Hilla8950692021-08-12 20:30:402566 });
2567
Urgau4f4fa422024-03-21 20:13:062568 let file_mapping = file_path_mapping(remap_path_prefix.clone(), &unstable_opts);
2569 let working_dir = file_mapping.to_real_filename(&working_dir);
Aaron Hilla8950692021-08-12 20:30:402570
jyncb6d0332023-12-19 18:24:052571 let verbose = matches.opt_present("verbose") || unstable_opts.verbose_internals;
2572
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582573 Options {
pierwill1642fdf2021-10-31 22:05:482574 assert_incr_state,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582575 crate_types,
2576 optimize: opt_level,
2577 debuginfo,
Augie Fackleraf9e5502023-07-12 21:07:342578 debuginfo_compression,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582579 lint_opts,
2580 lint_cap,
2581 describe_lints,
2582 output_types,
2583 search_paths,
Maybe Waffle54415232024-02-15 00:03:342584 maybe_sysroot: Some(sysroot),
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582585 target_triple,
2586 test,
2587 incremental,
Alex Macleod59f6f042023-10-13 17:28:342588 untracked_state_hash: Default::default(),
Joshua Nelson3c9765c2022-07-06 12:44:472589 unstable_opts,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582590 prints,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582591 cg,
2592 error_format,
David Wood44c1fcc2022-07-06 10:57:412593 diagnostic_width,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582594 externs,
Zalathar78edefe2024-11-11 10:42:422595 unstable_features,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582596 crate_name,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582597 libs,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582598 debug_assertions,
2599 actually_rustdoc: false,
Vadim Petrochenkovda4ce6b2023-02-06 17:57:452600 resolve_doc_links: ResolveDocLinks::ExportedMetadata,
Nicholas Nethercote32de78c2024-01-10 01:47:222601 trimmed_def_paths: false,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582602 cli_forced_codegen_units: codegen_units,
Wesley Wiser7c6345d2022-10-27 00:28:252603 cli_forced_local_thinlto_off: disable_local_thinlto,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582604 remap_path_prefix,
Joshua Nelson39648ea2021-04-27 16:25:122605 real_rust_source_base_dir,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582606 edition,
2607 json_artifact_notifications,
est313f2ca472020-06-30 18:17:072608 json_unused_externs,
Aaron Hill63523e42021-12-04 19:34:202609 json_future_incompat,
Mark Rousskovdd6df0d2019-11-04 02:42:032610 pretty,
Aaron Hilla8950692021-08-12 20:30:402611 working_dir,
Trevor Gross6a1c10b2022-12-19 18:09:402612 color,
Guillaume Gomez486e55e2023-11-27 12:47:262613 logical_env,
jyncb6d0332023-12-19 18:24:052614 verbose,
Mark Rousskovdd6df0d2019-11-04 02:42:032615 }
2616}
2617
Nicholas Nethercoted58e3722023-12-17 23:57:262618fn parse_pretty(early_dcx: &EarlyDiagCtxt, unstable_opts: &UnstableOptions) -> Option<PpMode> {
Joshua Nelson23bbd652021-03-25 19:48:212619 use PpMode::*;
LeSeulArtichaut3ed189e2021-02-18 19:21:182620
Joshua Nelson3c9765c2022-07-06 12:44:472621 let first = match unstable_opts.unpretty.as_deref()? {
Joshua Nelson23bbd652021-03-25 19:48:212622 "normal" => Source(PpSourceMode::Normal),
2623 "identified" => Source(PpSourceMode::Identified),
Joshua Nelson23bbd652021-03-25 19:48:212624 "expanded" => Source(PpSourceMode::Expanded),
2625 "expanded,identified" => Source(PpSourceMode::ExpandedIdentified),
2626 "expanded,hygiene" => Source(PpSourceMode::ExpandedHygiene),
Nicholas Nethercote1467ba02023-10-10 01:17:062627 "ast-tree" => AstTree,
2628 "ast-tree,expanded" => AstTreeExpanded,
Joshua Nelson23bbd652021-03-25 19:48:212629 "hir" => Hir(PpHirMode::Normal),
2630 "hir,identified" => Hir(PpHirMode::Identified),
2631 "hir,typed" => Hir(PpHirMode::Typed),
2632 "hir-tree" => HirTree,
2633 "thir-tree" => ThirTree,
b-naber94381262023-01-26 22:35:242634 "thir-flat" => ThirFlat,
Joshua Nelson23bbd652021-03-25 19:48:212635 "mir" => Mir,
Oğuz Ağcayazı38836452023-11-14 13:21:552636 "stable-mir" => StableMir,
Joshua Nelson23bbd652021-03-25 19:48:212637 "mir-cfg" => MirCFG,
Nicholas Nethercote3a1b8e62023-12-20 03:53:502638 name => early_dcx.early_fatal(format!(
许杰友 Jieyou Xu (Joe)cef812b2023-06-22 21:56:092639 "argument to `unpretty` must be one of `normal`, `identified`, \
Alex Macleod1d64b852022-03-06 12:43:302640 `expanded`, `expanded,identified`, `expanded,hygiene`, \
Joshua Nelson23bbd652021-03-25 19:48:212641 `ast-tree`, `ast-tree,expanded`, `hir`, `hir,identified`, \
Oğuz Ağcayazı38836452023-11-14 13:21:552642 `hir,typed`, `hir-tree`, `thir-tree`, `thir-flat`, `mir`, `stable-mir`, or \
b-naber94381262023-01-26 22:35:242643 `mir-cfg`; got {name}"
许杰友 Jieyou Xu (Joe)cef812b2023-06-22 21:56:092644 )),
Joshua Nelson23bbd652021-03-25 19:48:212645 };
Oli Schereree3c8352022-08-31 13:09:262646 debug!("got unpretty option: {first:?}");
Joshua Nelson23bbd652021-03-25 19:48:212647 Some(first)
Nick Cameroncacd6b62015-01-30 08:44:272648}
2649
Aaron Hill14986082019-07-20 20:34:412650pub fn make_crate_type_option() -> RustcOptGroup {
Zalathar001013c2024-11-07 11:47:152651 make_opt(
2652 OptionStability::Stable,
2653 OptionKind::Multi,
Aaron Hill14986082019-07-20 20:34:412654 "",
2655 "crate-type",
2656 "Comma separated list of types of crates
2657 for the compiler to emit",
2658 "[bin|lib|rlib|dylib|cdylib|staticlib|proc-macro]",
2659 )
2660}
2661
Santiago Pastorino52a47d42018-03-06 05:29:032662pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateType>, String> {
Brian Anderson1c3655b2014-07-20 04:11:262663 let mut crate_types: Vec<CrateType> = Vec::new();
Jorge Apariciod5d7e652015-01-31 17:20:462664 for unparsed_crate_type in &list_list {
Jorge Aparicio00f3c3f2014-11-27 18:53:342665 for part in unparsed_crate_type.split(',') {
Brian Anderson1c3655b2014-07-20 04:11:262666 let new_part = match part {
Santiago Pastorino52a47d42018-03-06 05:29:032667 "lib" => default_lib_output(),
Mark Rousskov2a934422018-07-26 17:13:112668 "rlib" => CrateType::Rlib,
2669 "staticlib" => CrateType::Staticlib,
2670 "dylib" => CrateType::Dylib,
2671 "cdylib" => CrateType::Cdylib,
2672 "bin" => CrateType::Executable,
2673 "proc-macro" => CrateType::ProcMacro,
Jubilee Youngde66e082022-03-25 05:11:052674 _ => return Err(format!("unknown crate type: `{part}`")),
Brian Anderson1c3655b2014-07-20 04:11:262675 };
Simonas Kazlauskasa6e84962015-02-09 17:30:222676 if !crate_types.contains(&new_part) {
2677 crate_types.push(new_part)
2678 }
Brian Anderson1c3655b2014-07-20 04:11:262679 }
2680 }
2681
Michael Kohl9873acc2017-05-28 06:49:142682 Ok(crate_types)
Brian Anderson1c3655b2014-07-20 04:11:262683}
2684
Guillaume Gomezded701b2016-03-15 08:09:292685pub mod nightly_options {
Nicholas Nethercote84ac80f2024-07-28 22:13:502686 use rustc_feature::UnstableFeatures;
2687
许杰友 Jieyou Xu (Joe)cef812b2023-06-22 21:56:092688 use super::{OptionStability, RustcOptGroup};
Nicholas Nethercotecce17012023-12-17 11:01:062689 use crate::EarlyDiagCtxt;
Guillaume Gomezded701b2016-03-15 08:09:292690
2691 pub fn is_unstable_enabled(matches: &getopts::Matches) -> bool {
Joshua Nelson622c48e2020-10-10 18:27:522692 match_is_nightly_build(matches)
2693 && matches.opt_strs("Z").iter().any(|x| *x == "unstable-options")
Guillaume Gomezded701b2016-03-15 08:09:292694 }
2695
Joshua Nelson622c48e2020-10-10 18:27:522696 pub fn match_is_nightly_build(matches: &getopts::Matches) -> bool {
2697 is_nightly_build(matches.opt_str("crate-name").as_deref())
2698 }
2699
Nicholas Nethercotede388882024-03-19 02:31:282700 fn is_nightly_build(krate: Option<&str>) -> bool {
Joshua Nelson622c48e2020-10-10 18:27:522701 UnstableFeatures::from_environment(krate).is_nightly_build()
Guillaume Gomezded701b2016-03-15 08:09:292702 }
2703
许杰友 Jieyou Xu (Joe)cef812b2023-06-22 21:56:092704 pub fn check_nightly_options(
Nicholas Nethercoted58e3722023-12-17 23:57:262705 early_dcx: &EarlyDiagCtxt,
许杰友 Jieyou Xu (Joe)cef812b2023-06-22 21:56:092706 matches: &getopts::Matches,
2707 flags: &[RustcOptGroup],
2708 ) {
Mark Rousskova06baa52019-12-22 22:42:042709 let has_z_unstable_option = matches.opt_strs("Z").iter().any(|x| *x == "unstable-options");
Joshua Nelson622c48e2020-10-10 18:27:522710 let really_allows_unstable_options = match_is_nightly_build(matches);
yukang12888d22023-09-09 16:01:322711 let mut nightly_options_on_stable = 0;
Guillaume Gomezded701b2016-03-15 08:09:292712
2713 for opt in flags.iter() {
2714 if opt.stability == OptionStability::Stable {
Santiago Pastorino52a47d42018-03-06 05:29:032715 continue;
Guillaume Gomezded701b2016-03-15 08:09:292716 }
Alex Crichton5c3d0e62017-06-08 21:20:552717 if !matches.opt_present(opt.name) {
Santiago Pastorino52a47d42018-03-06 05:29:032718 continue;
Guillaume Gomezded701b2016-03-15 08:09:292719 }
Alex Crichton5c3d0e62017-06-08 21:20:552720 if opt.name != "Z" && !has_z_unstable_option {
Nicholas Nethercote3a1b8e62023-12-20 03:53:502721 early_dcx.early_fatal(format!(
许杰友 Jieyou Xu (Joe)cef812b2023-06-22 21:56:092722 "the `-Z unstable-options` flag must also be passed to enable \
Santiago Pastorino52a47d42018-03-06 05:29:032723 the flag `{}`",
许杰友 Jieyou Xu (Joe)cef812b2023-06-22 21:56:092724 opt.name
2725 ));
Guillaume Gomezded701b2016-03-15 08:09:292726 }
2727 if really_allows_unstable_options {
Santiago Pastorino52a47d42018-03-06 05:29:032728 continue;
Guillaume Gomezded701b2016-03-15 08:09:292729 }
2730 match opt.stability {
2731 OptionStability::Unstable => {
yukang12888d22023-09-09 16:01:322732 nightly_options_on_stable += 1;
Santiago Pastorino52a47d42018-03-06 05:29:032733 let msg = format!(
Nicholas Nethercote01e33a32023-05-16 06:04:032734 "the option `{}` is only accepted on the nightly compiler",
Santiago Pastorino52a47d42018-03-06 05:29:032735 opt.name
2736 );
Nicholas Nethercote3a1b8e62023-12-20 03:53:502737 let _ = early_dcx.early_err(msg);
Guillaume Gomezded701b2016-03-15 08:09:292738 }
Guillaume Gomezded701b2016-03-15 08:09:292739 OptionStability::Stable => {}
2740 }
2741 }
yukang12888d22023-09-09 16:01:322742 if nightly_options_on_stable > 0 {
Nicholas Nethercoted58e3722023-12-17 23:57:262743 early_dcx
yukang12888d22023-09-09 16:01:322744 .early_help("consider switching to a nightly toolchain: `rustup default nightly`");
Nicholas Nethercoted58e3722023-12-17 23:57:262745 early_dcx.early_note("selecting a toolchain with `+toolchain` arguments require a rustup proxy; see <https://rust-lang.github.io/rustup/concepts/index.html>");
2746 early_dcx.early_note("for more information about Rust's stability policy, see <https://doc.rust-lang.org/book/appendix-07-nightly-rust.html#unstable-features>");
Nicholas Nethercote3a1b8e62023-12-20 03:53:502747 early_dcx.early_fatal(format!(
yukang12888d22023-09-09 16:01:322748 "{} nightly option{} were parsed",
2749 nightly_options_on_stable,
2750 if nightly_options_on_stable > 1 { "s" } else { "" }
2751 ));
2752 }
Guillaume Gomezded701b2016-03-15 08:09:292753 }
2754}
2755
Alex Crichton3cb9fa22015-01-20 23:45:072756impl fmt::Display for CrateType {
Zack M. Davis5b22d9b2018-08-30 05:02:422757 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Valerii Hiora70a79a92014-06-11 07:48:172758 match *self {
Mark Rousskov2a934422018-07-26 17:13:112759 CrateType::Executable => "bin".fmt(f),
2760 CrateType::Dylib => "dylib".fmt(f),
2761 CrateType::Rlib => "rlib".fmt(f),
2762 CrateType::Staticlib => "staticlib".fmt(f),
2763 CrateType::Cdylib => "cdylib".fmt(f),
2764 CrateType::ProcMacro => "proc-macro".fmt(f),
Valerii Hiora70a79a92014-06-11 07:48:172765 }
2766 }
2767}
Nick Cameron37ca3672014-05-06 11:38:012768
Nicholas Nethercotea09b1d32024-03-05 05:53:242769impl IntoDiagArg for CrateType {
2770 fn into_diag_arg(self) -> DiagArgValue {
2771 self.to_string().into_diag_arg()
David Woodd4500482022-08-30 16:01:542772 }
2773}
2774
Mark Rousskovdd6df0d2019-11-04 02:42:032775#[derive(Copy, Clone, PartialEq, Debug)]
2776pub enum PpSourceMode {
Joshua Nelson23bbd652021-03-25 19:48:212777 /// `-Zunpretty=normal`
LeSeulArtichaut3ed189e2021-02-18 19:21:182778 Normal,
Joshua Nelson23bbd652021-03-25 19:48:212779 /// `-Zunpretty=expanded`
LeSeulArtichaut3ed189e2021-02-18 19:21:182780 Expanded,
Joshua Nelson23bbd652021-03-25 19:48:212781 /// `-Zunpretty=identified`
LeSeulArtichaut3ed189e2021-02-18 19:21:182782 Identified,
Joshua Nelson23bbd652021-03-25 19:48:212783 /// `-Zunpretty=expanded,identified`
LeSeulArtichaut3ed189e2021-02-18 19:21:182784 ExpandedIdentified,
Joshua Nelson23bbd652021-03-25 19:48:212785 /// `-Zunpretty=expanded,hygiene`
LeSeulArtichaut3ed189e2021-02-18 19:21:182786 ExpandedHygiene,
2787}
2788
2789#[derive(Copy, Clone, PartialEq, Debug)]
2790pub enum PpHirMode {
2791 /// `-Zunpretty=hir`
2792 Normal,
2793 /// `-Zunpretty=hir,identified`
2794 Identified,
2795 /// `-Zunpretty=hir,typed`
2796 Typed,
Mark Rousskovdd6df0d2019-11-04 02:42:032797}
2798
2799#[derive(Copy, Clone, PartialEq, Debug)]
Orion Gonzaleza007d342024-08-27 18:04:472800/// Pretty print mode
Mark Rousskovdd6df0d2019-11-04 02:42:032801pub enum PpMode {
LeSeulArtichaut3ed189e2021-02-18 19:21:182802 /// Options that print the source code, i.e.
bjorn32f844842021-06-25 09:56:142803 /// `-Zunpretty=normal` and `-Zunpretty=expanded`
LeSeulArtichaut3ed189e2021-02-18 19:21:182804 Source(PpSourceMode),
Nicholas Nethercote1467ba02023-10-10 01:17:062805 /// `-Zunpretty=ast-tree`
2806 AstTree,
2807 /// `-Zunpretty=ast-tree,expanded`
2808 AstTreeExpanded,
LeSeulArtichaut3ed189e2021-02-18 19:21:182809 /// Options that print the HIR, i.e. `-Zunpretty=hir`
2810 Hir(PpHirMode),
2811 /// `-Zunpretty=hir-tree`
2812 HirTree,
LeSeulArtichaut6bf41472021-03-07 14:09:392813 /// `-Zunpretty=thir-tree`
2814 ThirTree,
est31ff2c6092023-03-03 03:10:462815 /// `-Zunpretty=thir-flat`
b-naber94381262023-01-26 22:35:242816 ThirFlat,
LeSeulArtichaut3ed189e2021-02-18 19:21:182817 /// `-Zunpretty=mir`
2818 Mir,
2819 /// `-Zunpretty=mir-cfg`
2820 MirCFG,
Oğuz Ağcayazı38836452023-11-14 13:21:552821 /// `-Zunpretty=stable-mir`
2822 StableMir,
Mark Rousskovdd6df0d2019-11-04 02:42:032823}
2824
2825impl PpMode {
Mark Rousskov7ec20dd32019-11-20 13:27:422826 pub fn needs_ast_map(&self) -> bool {
Mark Rousskovdd6df0d2019-11-04 02:42:032827 use PpMode::*;
2828 use PpSourceMode::*;
2829 match *self {
Nicholas Nethercote1467ba02023-10-10 01:17:062830 Source(Normal | Identified) | AstTree => false,
Mark Rousskovdd6df0d2019-11-04 02:42:032831
bjorn32f844842021-06-25 09:56:142832 Source(Expanded | ExpandedIdentified | ExpandedHygiene)
Nicholas Nethercote1467ba02023-10-10 01:17:062833 | AstTreeExpanded
LeSeulArtichaut3ed189e2021-02-18 19:21:182834 | Hir(_)
2835 | HirTree
LeSeulArtichaut6bf41472021-03-07 14:09:392836 | ThirTree
b-naber94381262023-01-26 22:35:242837 | ThirFlat
LeSeulArtichaut3ed189e2021-02-18 19:21:182838 | Mir
Oğuz Ağcayazıae179a02023-11-08 09:37:262839 | MirCFG
Oğuz Ağcayazı38836452023-11-14 13:21:552840 | StableMir => true,
Mark Rousskovdd6df0d2019-11-04 02:42:032841 }
2842 }
Michael Goulet26ecd442022-07-17 03:35:542843 pub fn needs_hir(&self) -> bool {
2844 use PpMode::*;
2845 match *self {
Nicholas Nethercote1467ba02023-10-10 01:17:062846 Source(_) | AstTree | AstTreeExpanded => false,
Michael Goulet26ecd442022-07-17 03:35:542847
Oğuz Ağcayazı38836452023-11-14 13:21:552848 Hir(_) | HirTree | ThirTree | ThirFlat | Mir | MirCFG | StableMir => true,
Michael Goulet26ecd442022-07-17 03:35:542849 }
2850 }
Mark Rousskovdd6df0d2019-11-04 02:42:032851
2852 pub fn needs_analysis(&self) -> bool {
2853 use PpMode::*;
Oğuz Ağcayazı38836452023-11-14 13:21:552854 matches!(*self, Hir(PpHirMode::Typed) | Mir | StableMir | MirCFG | ThirTree | ThirFlat)
Mark Rousskovdd6df0d2019-11-04 02:42:032855 }
2856}
2857
Nicholas Nethercote4b90b262023-11-29 22:45:032858#[derive(Clone, Hash, PartialEq, Eq, Debug)]
2859pub enum WasiExecModel {
2860 Command,
2861 Reactor,
2862}
2863
Andy Russell4e35cbb22018-11-12 18:05:202864/// Command-line arguments passed to the compiler have to be incorporated with
Michael Woerister32414312016-08-02 20:53:582865/// the dependency tracking system for incremental compilation. This module
2866/// provides some utilities to make this more convenient.
2867///
Andy Russell4e35cbb22018-11-12 18:05:202868/// The values of all command-line arguments that are relevant for dependency
Michael Woerister32414312016-08-02 20:53:582869/// tracking are hashed into a single value that determines whether the
2870/// incremental compilation cache can be re-used or not. This hashing is done
Alexander Regueiroc1d29ee2019-09-06 02:57:442871/// via the `DepTrackingHash` trait defined below, since the standard `Hash`
2872/// implementation might not be suitable (e.g., arguments are stored in a `Vec`,
Michael Woerister32414312016-08-02 20:53:582873/// the hash of which is order dependent, but we might not want the order of
2874/// arguments to make a difference for the hash).
2875///
Alexander Regueiroc1d29ee2019-09-06 02:57:442876/// However, since the value provided by `Hash::hash` often *is* suitable,
Michael Woerister32414312016-08-02 20:53:582877/// especially for primitive types, there is the
Alexander Regueiroc1d29ee2019-09-06 02:57:442878/// `impl_dep_tracking_hash_via_hash!()` macro that allows to simply reuse the
2879/// `Hash` implementation for `DepTrackingHash`. It's important though that
Michael Woerister32414312016-08-02 20:53:582880/// we have an opt-in scheme here, so one is hopefully forced to think about
Andy Russell4e35cbb22018-11-12 18:05:202881/// how the hash should be calculated when adding a new command-line argument.
Jacob Pratt49c82f32022-05-20 23:51:092882pub(crate) mod dep_tracking {
Nicholas Nethercote84ac80f2024-07-28 22:13:502883 use std::collections::BTreeMap;
2884 use std::hash::{DefaultHasher, Hash};
2885 use std::num::NonZero;
2886 use std::path::PathBuf;
2887
Folkert de Vries47573bf2024-12-18 21:03:072888 use rustc_abi::Align;
Nicholas Nethercote84ac80f2024-07-28 22:13:502889 use rustc_data_structures::fx::FxIndexMap;
2890 use rustc_data_structures::stable_hasher::Hash64;
2891 use rustc_errors::LanguageIdentifier;
2892 use rustc_feature::UnstableFeatures;
Nicholas Nethercote84ac80f2024-07-28 22:13:502893 use rustc_span::RealFileName;
Michael Gouletc682aa12024-09-22 23:05:042894 use rustc_span::edition::Edition;
Nicholas Nethercote84ac80f2024-07-28 22:13:502895 use rustc_target::spec::{
2896 CodeModel, FramePointer, MergeFunctions, OnBrokenPipe, PanicStrategy, RelocModel,
Noratrieba26450c2024-10-17 17:02:322897 RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, SymbolVisibility, TargetTuple,
David Lattimoref48194e2024-09-30 22:55:102898 TlsModel, WasmCAbi,
Nicholas Nethercote84ac80f2024-07-28 22:13:502899 };
2900
Mark Rousskova06baa52019-12-22 22:42:042901 use super::{
Zalathar3407fcc2024-03-08 07:07:042902 BranchProtection, CFGuard, CFProtection, CollapseMacroDebuginfo, CoverageOptions,
Kornel88b9edc2024-04-14 12:52:582903 CrateType, DebugInfo, DebugInfoCompression, ErrorOutputType, FmtDebug, FunctionReturn,
Zalathar3407fcc2024-03-08 07:07:042904 InliningThreshold, InstrumentCoverage, InstrumentXRay, LinkerPluginLto, LocationDetail,
Scott McMurraya7fc76a2024-12-05 08:47:362905 LtoCli, MirStripDebugInfo, NextSolverConfig, OomStrategy, OptLevel, OutFileName,
2906 OutputType, OutputTypes, PatchableFunctionEntry, Polonius, RemapPathScopeComponents,
2907 ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath,
2908 SymbolManglingVersion, WasiExecModel,
Mark Rousskova06baa52019-12-22 22:42:042909 };
Mark Rousskovcc2c33a2019-11-29 21:05:282910 use crate::lint;
Alex Macleod59f6f042023-10-13 17:28:342911 use crate::utils::NativeLib;
Michael Woerister32414312016-08-02 20:53:582912
Nicholas Nethercotede388882024-03-19 02:31:282913 pub(crate) trait DepTrackingHash {
Aaron Hill99f652f2021-06-20 00:22:142914 fn hash(
2915 &self,
2916 hasher: &mut DefaultHasher,
2917 error_format: ErrorOutputType,
2918 for_crate_hash: bool,
2919 );
Michael Woerister32414312016-08-02 20:53:582920 }
2921
2922 macro_rules! impl_dep_tracking_hash_via_hash {
Joshua Nelsondd43d132021-04-22 15:45:082923 ($($t:ty),+ $(,)?) => {$(
Michael Woerister32414312016-08-02 20:53:582924 impl DepTrackingHash for $t {
Aaron Hill99f652f2021-06-20 00:22:142925 fn hash(&self, hasher: &mut DefaultHasher, _: ErrorOutputType, _for_crate_hash: bool) {
Michael Woerister32414312016-08-02 20:53:582926 Hash::hash(self, hasher);
2927 }
2928 }
Joshua Nelsondd43d132021-04-22 15:45:082929 )+};
Michael Woerister32414312016-08-02 20:53:582930 }
2931
Joshua Nelson76502de2021-04-15 23:36:252932 impl<T: DepTrackingHash> DepTrackingHash for Option<T> {
Aaron Hill99f652f2021-06-20 00:22:142933 fn hash(
2934 &self,
2935 hasher: &mut DefaultHasher,
2936 error_format: ErrorOutputType,
2937 for_crate_hash: bool,
2938 ) {
Joshua Nelson76502de2021-04-15 23:36:252939 match self {
2940 Some(x) => {
2941 Hash::hash(&1, hasher);
Aaron Hill99f652f2021-06-20 00:22:142942 DepTrackingHash::hash(x, hasher, error_format, for_crate_hash);
Joshua Nelson76502de2021-04-15 23:36:252943 }
2944 None => Hash::hash(&0, hasher),
2945 }
2946 }
2947 }
2948
Joshua Nelsondd43d132021-04-22 15:45:082949 impl_dep_tracking_hash_via_hash!(
2950 bool,
2951 usize,
Markus Reiter746a58d2024-01-29 22:59:092952 NonZero<usize>,
Joshua Nelsondd43d132021-04-22 15:45:082953 u64,
Alex Macleod59f6f042023-10-13 17:28:342954 Hash64,
Joshua Nelsondd43d132021-04-22 15:45:082955 String,
2956 PathBuf,
2957 lint::Level,
Joshua Nelson76502de2021-04-15 23:36:252958 WasiExecModel,
2959 u32,
Jubilee Youngb3a19752024-05-04 23:19:422960 FramePointer,
Joshua Nelson76502de2021-04-15 23:36:252961 RelocModel,
2962 CodeModel,
2963 TlsModel,
2964 InstrumentCoverage,
Zalathar3407fcc2024-03-08 07:07:042965 CoverageOptions,
Oleksii Lozovskyi0e60df92022-09-24 11:02:442966 InstrumentXRay,
Joshua Nelsondd43d132021-04-22 15:45:082967 CrateType,
2968 MergeFunctions,
Martin Nordholtscde0cde2024-04-28 16:02:212969 OnBrokenPipe,
Joshua Nelsondd43d132021-04-22 15:45:082970 PanicStrategy,
2971 RelroLevel,
Joshua Nelsondd43d132021-04-22 15:45:082972 OptLevel,
2973 LtoCli,
2974 DebugInfo,
Augie Fackleraf9e5502023-07-12 21:07:342975 DebugInfoCompression,
Scott McMurraya7fc76a2024-12-05 08:47:362976 MirStripDebugInfo,
Andrew Zhogin8507f512024-01-10 18:36:052977 CollapseMacroDebuginfo,
Joshua Nelsondd43d132021-04-22 15:45:082978 UnstableFeatures,
Luqman Adendb555e12021-03-25 04:45:092979 NativeLib,
Joshua Nelsondd43d132021-04-22 15:45:082980 SanitizerSet,
2981 CFGuard,
Andrew Brown8d6c9732022-01-28 17:48:592982 CFProtection,
Noratrieba26450c2024-10-17 17:02:322983 TargetTuple,
Joshua Nelsondd43d132021-04-22 15:45:082984 Edition,
2985 LinkerPluginLto,
Vadim Petrochenkovda4ce6b2023-02-06 17:57:452986 ResolveDocLinks,
Joshua Nelson76502de2021-04-15 23:36:252987 SplitDebuginfo,
Michael Woerister822957f2022-07-04 12:04:352988 SplitDwarfKind,
Benjamin A. Bjørnsethbb9dee92021-04-06 19:37:492989 StackProtector,
Joshua Nelsondd43d132021-04-22 15:45:082990 SwitchWithOptPath,
Joshua Nelson76502de2021-04-15 23:36:252991 SymbolManglingVersion,
David Lattimoref48194e2024-09-30 22:55:102992 SymbolVisibility,
Urgau30f94712023-08-23 09:18:202993 RemapPathScopeComponents,
Joshua Nelson76502de2021-04-15 23:36:252994 SourceFileHashAlgorithm,
Jing Peng9b1a1e12023-02-26 20:27:272995 OutFileName,
Aaron Hill99f652f2021-06-20 00:22:142996 OutputType,
Aaron Hilla8950692021-08-12 20:30:402997 RealFileName,
Hudson Ayersa9a13932021-10-14 00:01:312998 LocationDetail,
Kornel88b9edc2024-04-14 12:52:582999 FmtDebug,
James McGregor837cc162021-07-13 11:14:263000 BranchProtection,
Amanieu d'Antrasaa362372021-10-06 14:52:543001 OomStrategy,
David Woodd5119c52022-03-28 08:36:203002 LanguageIdentifier,
lcnr5d97ada2023-12-14 12:00:233003 NextSolverConfig,
Matthew Maurerac7595f2023-12-12 21:32:433004 PatchableFunctionEntry,
Rémy Rakic4f7a27b2023-06-30 11:55:383005 Polonius,
Ben Kimockfcdd99e2023-11-07 00:55:053006 InliningThreshold,
Miguel Ojeda2d476222023-10-18 14:58:173007 FunctionReturn,
daxpeddaf09c19a2024-02-27 22:06:443008 WasmCAbi,
Folkert de Vries47573bf2024-12-18 21:03:073009 Align,
Joshua Nelsondd43d132021-04-22 15:45:083010 );
Michael Woerister32414312016-08-02 20:53:583011
Michael Woerister32414312016-08-02 20:53:583012 impl<T1, T2> DepTrackingHash for (T1, T2)
Santiago Pastorino52a47d42018-03-06 05:29:033013 where
3014 T1: DepTrackingHash,
3015 T2: DepTrackingHash,
Michael Woerister32414312016-08-02 20:53:583016 {
Aaron Hill99f652f2021-06-20 00:22:143017 fn hash(
3018 &self,
3019 hasher: &mut DefaultHasher,
3020 error_format: ErrorOutputType,
3021 for_crate_hash: bool,
3022 ) {
Michael Woerister32414312016-08-02 20:53:583023 Hash::hash(&0, hasher);
Aaron Hill99f652f2021-06-20 00:22:143024 DepTrackingHash::hash(&self.0, hasher, error_format, for_crate_hash);
Michael Woerister32414312016-08-02 20:53:583025 Hash::hash(&1, hasher);
Aaron Hill99f652f2021-06-20 00:22:143026 DepTrackingHash::hash(&self.1, hasher, error_format, for_crate_hash);
Michael Woerister32414312016-08-02 20:53:583027 }
3028 }
3029
Vadim Chugunov13477c72016-11-24 00:09:513030 impl<T1, T2, T3> DepTrackingHash for (T1, T2, T3)
Santiago Pastorino52a47d42018-03-06 05:29:033031 where
3032 T1: DepTrackingHash,
3033 T2: DepTrackingHash,
3034 T3: DepTrackingHash,
Vadim Chugunov13477c72016-11-24 00:09:513035 {
Aaron Hill99f652f2021-06-20 00:22:143036 fn hash(
3037 &self,
3038 hasher: &mut DefaultHasher,
3039 error_format: ErrorOutputType,
3040 for_crate_hash: bool,
3041 ) {
Vadim Chugunov13477c72016-11-24 00:09:513042 Hash::hash(&0, hasher);
Aaron Hill99f652f2021-06-20 00:22:143043 DepTrackingHash::hash(&self.0, hasher, error_format, for_crate_hash);
Vadim Chugunov13477c72016-11-24 00:09:513044 Hash::hash(&1, hasher);
Aaron Hill99f652f2021-06-20 00:22:143045 DepTrackingHash::hash(&self.1, hasher, error_format, for_crate_hash);
Vadim Chugunov13477c72016-11-24 00:09:513046 Hash::hash(&2, hasher);
Aaron Hill99f652f2021-06-20 00:22:143047 DepTrackingHash::hash(&self.2, hasher, error_format, for_crate_hash);
Vadim Chugunov13477c72016-11-24 00:09:513048 }
3049 }
3050
Aaron Hill605513a2021-05-26 00:43:023051 impl<T: DepTrackingHash> DepTrackingHash for Vec<T> {
Aaron Hill99f652f2021-06-20 00:22:143052 fn hash(
3053 &self,
3054 hasher: &mut DefaultHasher,
3055 error_format: ErrorOutputType,
3056 for_crate_hash: bool,
3057 ) {
Aaron Hill605513a2021-05-26 00:43:023058 Hash::hash(&self.len(), hasher);
3059 for (index, elem) in self.iter().enumerate() {
3060 Hash::hash(&index, hasher);
Aaron Hill99f652f2021-06-20 00:22:143061 DepTrackingHash::hash(elem, hasher, error_format, for_crate_hash);
3062 }
3063 }
3064 }
3065
Guillaume Gomez486e55e2023-11-27 12:47:263066 impl<T: DepTrackingHash, V: DepTrackingHash> DepTrackingHash for FxIndexMap<T, V> {
3067 fn hash(
3068 &self,
3069 hasher: &mut DefaultHasher,
3070 error_format: ErrorOutputType,
3071 for_crate_hash: bool,
3072 ) {
3073 Hash::hash(&self.len(), hasher);
3074 for (key, value) in self.iter() {
3075 DepTrackingHash::hash(key, hasher, error_format, for_crate_hash);
3076 DepTrackingHash::hash(value, hasher, error_format, for_crate_hash);
3077 }
3078 }
3079 }
3080
Aaron Hill99f652f2021-06-20 00:22:143081 impl DepTrackingHash for OutputTypes {
3082 fn hash(
3083 &self,
3084 hasher: &mut DefaultHasher,
3085 error_format: ErrorOutputType,
3086 for_crate_hash: bool,
3087 ) {
3088 Hash::hash(&self.0.len(), hasher);
3089 for (key, val) in &self.0 {
3090 DepTrackingHash::hash(key, hasher, error_format, for_crate_hash);
3091 if !for_crate_hash {
3092 DepTrackingHash::hash(val, hasher, error_format, for_crate_hash);
3093 }
Aaron Hill605513a2021-05-26 00:43:023094 }
3095 }
3096 }
3097
Michael Woerister32414312016-08-02 20:53:583098 // This is a stable hash because BTreeMap is a sorted container
Jacob Pratt49c82f32022-05-20 23:51:093099 pub(crate) fn stable_hash(
Santiago Pastorino52a47d42018-03-06 05:29:033100 sub_hashes: BTreeMap<&'static str, &dyn DepTrackingHash>,
3101 hasher: &mut DefaultHasher,
3102 error_format: ErrorOutputType,
Aaron Hill99f652f2021-06-20 00:22:143103 for_crate_hash: bool,
Santiago Pastorino52a47d42018-03-06 05:29:033104 ) {
Michael Woerister32414312016-08-02 20:53:583105 for (key, sub_hash) in sub_hashes {
3106 // Using Hash::hash() instead of DepTrackingHash::hash() is fine for
3107 // the keys, as they are just plain strings
3108 Hash::hash(&key.len(), hasher);
3109 Hash::hash(key, hasher);
Aaron Hill99f652f2021-06-20 00:22:143110 sub_hash.hash(hasher, error_format, for_crate_hash);
Michael Woerister32414312016-08-02 20:53:583111 }
3112 }
3113}
Amanieu d'Antrasaa362372021-10-06 14:52:543114
3115/// Default behavior to use in out-of-memory situations.
3116#[derive(Clone, Copy, PartialEq, Hash, Debug, Encodable, Decodable, HashStable_Generic)]
3117pub enum OomStrategy {
3118 /// Generate a panic that can be caught by `catch_unwind`.
3119 Panic,
3120
3121 /// Abort the process immediately.
3122 Abort,
3123}
3124
3125impl OomStrategy {
3126 pub const SYMBOL: &'static str = "__rust_alloc_error_handler_should_panic";
3127
3128 pub fn should_panic(self) -> u8 {
3129 match self {
3130 OomStrategy::Panic => 1,
3131 OomStrategy::Abort => 0,
3132 }
3133 }
3134}
Nika Layzell6d1650f2022-06-18 18:15:033135
3136/// How to run proc-macro code when building this crate
3137#[derive(Clone, Copy, PartialEq, Hash, Debug)]
3138pub enum ProcMacroExecutionStrategy {
3139 /// Run the proc-macro code on the same thread as the server.
3140 SameThread,
3141
3142 /// Run the proc-macro code on a different thread.
3143 CrossThread,
3144}
Joshua Nelsoneb53eea2022-12-29 21:08:093145
Andrew Zhogin8507f512024-01-10 18:36:053146/// How to perform collapse macros debug info
3147/// if-ext - if macro from different crate (related to callsite code)
3148/// | cmd \ attr | no | (unspecified) | external | yes |
3149/// | no | no | no | no | no |
3150/// | (unspecified) | no | no | if-ext | yes |
3151/// | external | no | if-ext | if-ext | yes |
3152/// | yes | yes | yes | yes | yes |
3153#[derive(Clone, Copy, PartialEq, Hash, Debug)]
3154pub enum CollapseMacroDebuginfo {
3155 /// Don't collapse debuginfo for the macro
3156 No = 0,
3157 /// Unspecified value
3158 Unspecified = 1,
3159 /// Collapse debuginfo if the macro comes from a different crate
3160 External = 2,
3161 /// Collapse debuginfo for the macro
3162 Yes = 3,
3163}
3164
Joshua Nelsoneb53eea2022-12-29 21:08:093165/// Which format to use for `-Z dump-mono-stats`
3166#[derive(Clone, Copy, PartialEq, Hash, Debug)]
3167pub enum DumpMonoStatsFormat {
3168 /// Pretty-print a markdown table
3169 Markdown,
3170 /// Emit structured JSON
3171 Json,
3172}
3173
3174impl DumpMonoStatsFormat {
3175 pub fn extension(self) -> &'static str {
3176 match self {
3177 Self::Markdown => "md",
3178 Self::Json => "json",
3179 }
3180 }
3181}
Rémy Rakic4f7a27b2023-06-30 11:55:383182
Matthew Maurerac7595f2023-12-12 21:32:433183/// `-Z patchable-function-entry` representation - how many nops to put before and after function
3184/// entry.
3185#[derive(Clone, Copy, PartialEq, Hash, Debug, Default)]
3186pub struct PatchableFunctionEntry {
3187 /// Nops before the entry
3188 prefix: u8,
3189 /// Nops after the entry
3190 entry: u8,
3191}
3192
3193impl PatchableFunctionEntry {
Florian Schmiderer7c563982024-05-02 21:19:023194 pub fn from_total_and_prefix_nops(
3195 total_nops: u8,
3196 prefix_nops: u8,
3197 ) -> Option<PatchableFunctionEntry> {
3198 if total_nops < prefix_nops {
Matthew Maurerac7595f2023-12-12 21:32:433199 None
3200 } else {
Florian Schmiderer7c563982024-05-02 21:19:023201 Some(Self { prefix: prefix_nops, entry: total_nops - prefix_nops })
Matthew Maurerac7595f2023-12-12 21:32:433202 }
3203 }
3204 pub fn prefix(&self) -> u8 {
3205 self.prefix
3206 }
3207 pub fn entry(&self) -> u8 {
3208 self.entry
3209 }
3210}
3211
Rémy Rakic4f7a27b2023-06-30 11:55:383212/// `-Zpolonius` values, enabling the borrow checker polonius analysis, and which version: legacy,
3213/// or future prototype.
Rémy Rakicd9c213c2023-10-20 15:32:223214#[derive(Clone, Copy, PartialEq, Hash, Debug, Default)]
Rémy Rakic4f7a27b2023-06-30 11:55:383215pub enum Polonius {
3216 /// The default value: disabled.
Rémy Rakicd9c213c2023-10-20 15:32:223217 #[default]
Rémy Rakic4f7a27b2023-06-30 11:55:383218 Off,
3219
3220 /// Legacy version, using datalog and the `polonius-engine` crate. Historical value for `-Zpolonius`.
3221 Legacy,
3222
Rémy Rakicb0126152023-06-30 13:18:113223 /// In-tree prototype, extending the NLL infrastructure.
Rémy Rakic4f7a27b2023-06-30 11:55:383224 Next,
3225}
3226
Rémy Rakic4f7a27b2023-06-30 11:55:383227impl Polonius {
3228 /// Returns whether the legacy version of polonius is enabled
3229 pub fn is_legacy_enabled(&self) -> bool {
3230 matches!(self, Polonius::Legacy)
3231 }
Rémy Rakicb0126152023-06-30 13:18:113232
3233 /// Returns whether the "next" version of polonius is enabled
3234 pub fn is_next_enabled(&self) -> bool {
3235 matches!(self, Polonius::Next)
3236 }
Rémy Rakic4f7a27b2023-06-30 11:55:383237}
Ben Kimockfcdd99e2023-11-07 00:55:053238
3239#[derive(Clone, Copy, PartialEq, Hash, Debug)]
3240pub enum InliningThreshold {
3241 Always,
3242 Sometimes(usize),
3243 Never,
3244}
3245
3246impl Default for InliningThreshold {
3247 fn default() -> Self {
3248 Self::Sometimes(100)
3249 }
3250}
Miguel Ojeda2d476222023-10-18 14:58:173251
3252/// The different settings that the `-Zfunction-return` flag can have.
3253#[derive(Clone, Copy, PartialEq, Hash, Debug, Default)]
3254pub enum FunctionReturn {
3255 /// Keep the function return unmodified.
3256 #[default]
3257 Keep,
3258
3259 /// Replace returns with jumps to thunk, without emitting the thunk.
3260 ThunkExtern,
3261}
Rémy Rakice0bb1c72024-08-28 21:13:563262
3263/// Whether extra span comments are included when dumping MIR, via the `-Z mir-include-spans` flag.
3264/// By default, only enabled in the NLL MIR dumps, and disabled in all other passes.
3265#[derive(Clone, Copy, Default, PartialEq, Debug)]
3266pub enum MirIncludeSpans {
3267 Off,
3268 On,
3269 /// Default: include extra comments in NLL MIR dumps only. Can be ignored and considered as
3270 /// `Off` in all other cases.
3271 #[default]
3272 Nll,
3273}
3274
3275impl MirIncludeSpans {
3276 /// Unless opting into extra comments for all passes, they can be considered disabled.
3277 /// The cases where a distinction between on/off and a per-pass value can exist will be handled
3278 /// in the passes themselves: i.e. the `Nll` value is considered off for all intents and
3279 /// purposes, except for the NLL MIR dump pass.
3280 pub fn is_enabled(self) -> bool {
3281 self == MirIncludeSpans::On
3282 }
3283}