blob: 1740d8fe967511beaa5b9349ede44716dbdfbbf7 [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
Alexander Regueiroc1d29ee2019-09-06 02:57:444use crate::lint;
5use crate::middle::cstore;
Mark Mansie957ed92019-02-05 17:20:456use crate::session::{early_error, early_warn, Session};
7use crate::session::search_paths::SearchPath;
Nick Cameron37ca3672014-05-06 11:38:018
Alexander Regueiroc1d29ee2019-09-06 02:57:449use rustc_data_structures::fx::FxHashSet;
10
Peter Jinb91d2112018-12-31 18:58:1311use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel};
Irina Popa38e96402017-12-08 19:18:2112use rustc_target::spec::{Target, TargetTriple};
Nick Cameron37ca3672014-05-06 11:38:0113
John Kåre Alsaker51938c62018-12-08 19:30:2314use syntax;
Mazdak Farrokhzadd945f982019-10-11 21:48:1615use syntax::ast::{self, IntTy, UintTy};
Donato Sciarra82607d22018-08-18 10:14:0316use syntax::source_map::{FileName, FilePathMapping};
Kurtis Nusbaum320fdaa2018-04-20 04:03:2117use syntax::edition::{Edition, EDITION_NAME_LIST, DEFAULT_EDITION};
Nicholas Nethercote26451ef2019-05-22 02:42:2318use syntax::symbol::{sym, Symbol};
Brian Andersonf14a0e22015-06-18 00:48:1619use syntax::feature_gate::UnstableFeatures;
Nick Cameron37ca3672014-05-06 11:38:0120
Alexander Regueiroc1d29ee2019-09-06 02:57:4421use errors::emitter::HumanReadableErrorType;
Mazdak Farrokhzadd945f982019-10-11 21:48:1622use errors::{ColorConfig, FatalError, Handler};
Jonathan Turner6ae350212016-06-21 22:08:1323
Nick Cameroncacd6b62015-01-30 08:44:2724use getopts;
Michael Woerister32414312016-08-02 20:53:5825
Alexander Regueiroc1d29ee2019-09-06 02:57:4426use std::collections::{BTreeMap, BTreeSet};
27use std::collections::btree_map::{
28 Iter as BTreeMapIter, Keys as BTreeMapKeysIter, Values as BTreeMapValuesIter,
29};
30use std::fmt;
31use std::str::{self, FromStr};
Alex Crichton10c31342016-09-29 00:23:3632use std::hash::Hasher;
33use std::collections::hash_map::DefaultHasher;
Michael Woerister32414312016-08-02 20:53:5834use std::iter::FromIterator;
Philipp Oppermann7b491902018-03-24 19:14:5935use std::path::{Path, PathBuf};
Nick Cameron37ca3672014-05-06 11:38:0136
Nick Cameron37ca3672014-05-06 11:38:0137pub struct Config {
Corey Richardson6b130e32014-07-23 18:56:3638 pub target: Target,
Eduard-Mihai Burtescu3ce31eb2017-08-05 09:27:2839 pub isize_ty: IntTy,
40 pub usize_ty: UintTy,
Nick Cameron37ca3672014-05-06 11:38:0141}
42
kennytm00dff0a2017-04-17 20:22:1643#[derive(Clone, Hash, Debug)]
Jorge Aparicio9af6aa32016-12-30 04:28:1144pub enum Sanitizer {
45 Address,
46 Leak,
47 Memory,
48 Thread,
49}
50
Wesley Wiser45482c62018-05-19 17:50:5851#[derive(Clone, Copy, Debug, PartialEq, Hash)]
Nick Cameron37ca3672014-05-06 11:38:0152pub enum OptLevel {
Santiago Pastorino52a47d42018-03-06 05:29:0353 No, // -O0
54 Less, // -O1
55 Default, // -O2
Brandon Edensb1337d32016-03-27 19:42:4756 Aggressive, // -O3
Santiago Pastorino52a47d42018-03-06 05:29:0357 Size, // -Os
58 SizeMin, // -Oz
Nick Cameron37ca3672014-05-06 11:38:0159}
60
Simonas Kazlauskasf38d0da2018-10-27 12:29:0661impl_stable_hash_via_hash!(OptLevel);
62
Michael Woerister24093a62018-09-04 15:57:1763/// This is what the `LtoCli` values get mapped to after resolving defaults and
64/// and taking other command line options into account.
Nicholas Nethercoteac6daed2019-10-20 04:54:5365#[derive(Clone, PartialEq)]
Alex Crichton8bde2ac2018-01-16 23:02:3166pub enum Lto {
67 /// Don't do any LTO whatsoever
68 No,
69
Alex Crichton8bde2ac2018-01-16 23:02:3170 /// Do a full crate graph LTO with ThinLTO
71 Thin,
72
73 /// Do a local graph LTO with ThinLTO (only relevant for multiple codegen
74 /// units).
75 ThinLocal,
76
77 /// Do a full crate graph LTO with "fat" LTO
78 Fat,
79}
80
Michael Woerister24093a62018-09-04 15:57:1781/// The different settings that the `-C lto` flag can have.
82#[derive(Clone, Copy, PartialEq, Hash, Debug)]
83pub enum LtoCli {
84 /// `-C lto=no`
85 No,
86 /// `-C lto=yes`
87 Yes,
88 /// `-C lto`
89 NoParam,
90 /// `-C lto=thin`
91 Thin,
92 /// `-C lto=fat`
93 Fat,
94 /// No `-C lto` flag passed
95 Unspecified,
96}
97
Michael Woeristera9810892018-04-25 13:45:0498#[derive(Clone, PartialEq, Hash)]
Michael Woerister04f425d2019-02-01 14:15:4399pub enum LinkerPluginLto {
Michael Woeristera9810892018-04-25 13:45:04100 LinkerPlugin(PathBuf),
Michael Woerister65ff4142018-07-03 14:33:11101 LinkerPluginAuto,
Michael Woeristera9810892018-04-25 13:45:04102 Disabled
103}
104
Michael Woerister04f425d2019-02-01 14:15:43105impl LinkerPluginLto {
Michael Woerister72df8042018-07-06 11:58:25106 pub fn enabled(&self) -> bool {
Michael Woeristera9810892018-04-25 13:45:04107 match *self {
Michael Woerister04f425d2019-02-01 14:15:43108 LinkerPluginLto::LinkerPlugin(_) |
109 LinkerPluginLto::LinkerPluginAuto => true,
110 LinkerPluginLto::Disabled => false,
Michael Woeristera9810892018-04-25 13:45:04111 }
112 }
113}
114
Michael Woerister7b1df422019-04-10 11:46:37115#[derive(Clone, PartialEq, Hash)]
Michael Woerister64ee32e2019-05-28 14:13:59116pub enum SwitchWithOptPath {
Michael Woerister7b1df422019-04-10 11:46:37117 Enabled(Option<PathBuf>),
118 Disabled,
119}
120
Michael Woerister64ee32e2019-05-28 14:13:59121impl SwitchWithOptPath {
Michael Woerister7b1df422019-04-10 11:46:37122 pub fn enabled(&self) -> bool {
123 match *self {
Michael Woerister64ee32e2019-05-28 14:13:59124 SwitchWithOptPath::Enabled(_) => true,
125 SwitchWithOptPath::Disabled => false,
Michael Woerister7b1df422019-04-10 11:46:37126 }
127 }
128}
129
Eduard-Mihai Burtescu20929632019-01-29 05:24:32130#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)]
131pub enum SymbolManglingVersion {
132 Legacy,
133 V0,
134}
135
136impl_stable_hash_via_hash!(SymbolManglingVersion);
137
Alex Crichton8bde2ac2018-01-16 23:02:31138#[derive(Clone, Copy, PartialEq, Hash)]
Mark Rousskov2bc71972018-07-26 17:41:10139pub enum DebugInfo {
140 None,
141 Limited,
142 Full,
Nick Cameron37ca3672014-05-06 11:38:01143}
144
Santiago Pastorino52a47d42018-03-06 05:29:03145#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, RustcEncodable, RustcDecodable)]
Niko Matsakisdc6e4142014-11-16 01:30:33146pub enum OutputType {
Alex Crichton8c963c02015-09-30 17:08:37147 Bitcode,
148 Assembly,
149 LlvmAssembly,
Jake Goulding9218f972017-02-16 21:59:09150 Mir,
Nick Cameron7720cf02016-12-23 06:39:20151 Metadata,
Alex Crichton8c963c02015-09-30 17:08:37152 Object,
153 Exe,
154 DepInfo,
Niko Matsakisdc6e4142014-11-16 01:30:33155}
156
Mark Rousskovac4439c2018-08-03 22:41:30157impl_stable_hash_via_hash!(OutputType);
Michael Woerister74d6b852017-09-18 10:14:52158
Felix S. Klock IIf90c21a2015-12-04 18:35:16159impl OutputType {
160 fn is_compatible_with_codegen_units_and_single_output_file(&self) -> bool {
161 match *self {
Alex Crichton955f2832019-04-25 16:06:38162 OutputType::Exe | OutputType::DepInfo | OutputType::Metadata => true,
Santiago Pastorino52a47d42018-03-06 05:29:03163 OutputType::Bitcode
164 | OutputType::Assembly
165 | OutputType::LlvmAssembly
166 | OutputType::Mir
Alex Crichton955f2832019-04-25 16:06:38167 | OutputType::Object => false,
Felix S. Klock IIf90c21a2015-12-04 18:35:16168 }
169 }
170
171 fn shorthand(&self) -> &'static str {
172 match *self {
173 OutputType::Bitcode => "llvm-bc",
174 OutputType::Assembly => "asm",
175 OutputType::LlvmAssembly => "llvm-ir",
Jake Goulding9218f972017-02-16 21:59:09176 OutputType::Mir => "mir",
Felix S. Klock IIf90c21a2015-12-04 18:35:16177 OutputType::Object => "obj",
Nick Cameron7720cf02016-12-23 06:39:20178 OutputType::Metadata => "metadata",
Felix S. Klock IIf90c21a2015-12-04 18:35:16179 OutputType::Exe => "link",
180 OutputType::DepInfo => "dep-info",
181 }
182 }
Niko Matsakis2f9fff212016-07-25 14:51:14183
Corey Farwellc3ea3582017-11-05 14:20:59184 fn from_shorthand(shorthand: &str) -> Option<Self> {
185 Some(match shorthand {
Santiago Pastorino52a47d42018-03-06 05:29:03186 "asm" => OutputType::Assembly,
187 "llvm-ir" => OutputType::LlvmAssembly,
188 "mir" => OutputType::Mir,
189 "llvm-bc" => OutputType::Bitcode,
190 "obj" => OutputType::Object,
191 "metadata" => OutputType::Metadata,
192 "link" => OutputType::Exe,
193 "dep-info" => OutputType::DepInfo,
Corey Farwellc3ea3582017-11-05 14:20:59194 _ => return None,
195 })
196 }
197
198 fn shorthands_display() -> String {
199 format!(
200 "`{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`, `{}`",
201 OutputType::Bitcode.shorthand(),
202 OutputType::Assembly.shorthand(),
203 OutputType::LlvmAssembly.shorthand(),
204 OutputType::Mir.shorthand(),
205 OutputType::Object.shorthand(),
206 OutputType::Metadata.shorthand(),
207 OutputType::Exe.shorthand(),
208 OutputType::DepInfo.shorthand(),
209 )
210 }
211
Niko Matsakis2f9fff212016-07-25 14:51:14212 pub fn extension(&self) -> &'static str {
213 match *self {
214 OutputType::Bitcode => "bc",
215 OutputType::Assembly => "s",
216 OutputType::LlvmAssembly => "ll",
Jake Goulding9218f972017-02-16 21:59:09217 OutputType::Mir => "mir",
Niko Matsakis2f9fff212016-07-25 14:51:14218 OutputType::Object => "o",
Nick Cameron7720cf02016-12-23 06:39:20219 OutputType::Metadata => "rmeta",
Niko Matsakis2f9fff212016-07-25 14:51:14220 OutputType::DepInfo => "d",
221 OutputType::Exe => "",
222 }
223 }
Felix S. Klock IIf90c21a2015-12-04 18:35:16224}
225
Philipp Hansch33137ff2019-06-10 08:59:03226/// The type of diagnostics output to generate.
Nick Cameronb286a2f2016-10-25 22:14:02227#[derive(Clone, Copy, Debug, PartialEq, Eq)]
228pub enum ErrorOutputType {
Philipp Hansche3516a12019-06-09 10:04:40229 /// Output meant for the consumption of humans.
Oliver Scherer39b21372019-03-25 10:16:58230 HumanReadable(HumanReadableErrorType),
Philipp Hansche3516a12019-06-09 10:04:40231 /// Output that's consumed by other tools such as `rustfix` or the `RLS`.
Oliver Scherer96404ee2019-03-12 12:06:43232 Json {
Philipp Hansch33137ff2019-06-10 08:59:03233 /// Render the JSON in a human readable way (with indents and newlines).
Oliver Scherer96404ee2019-03-12 12:06:43234 pretty: bool,
Philipp Hansche3516a12019-06-09 10:04:40235 /// The JSON output includes a `rendered` field that includes the rendered
236 /// human output.
Oliver Scherer39b21372019-03-25 10:16:58237 json_rendered: HumanReadableErrorType,
Oliver Scherer96404ee2019-03-12 12:06:43238 },
Nick Cameronb286a2f2016-10-25 22:14:02239}
240
241impl Default for ErrorOutputType {
Alexander Regueiroc1d29ee2019-09-06 02:57:44242 fn default() -> Self {
243 Self::HumanReadable(HumanReadableErrorType::Default(ColorConfig::Auto))
Nick Cameronb286a2f2016-10-25 22:14:02244 }
245}
246
Alexander Regueiroc1d29ee2019-09-06 02:57:44247/// Use tree-based collections to cheaply get a deterministic `Hash` implementation.
248/// *Do not* switch `BTreeMap` out for an unsorted container type! That would break
249/// dependency tracking for command-line arguments.
Michael Woerister32414312016-08-02 20:53:58250#[derive(Clone, Hash)]
251pub struct OutputTypes(BTreeMap<OutputType, Option<PathBuf>>);
Nick Cameron37ca3672014-05-06 11:38:01252
Mark Rousskovac4439c2018-08-03 22:41:30253impl_stable_hash_via_hash!(OutputTypes);
Michael Woerister74d6b852017-09-18 10:14:52254
Michael Woerister32414312016-08-02 20:53:58255impl OutputTypes {
256 pub fn new(entries: &[(OutputType, Option<PathBuf>)]) -> OutputTypes {
Santiago Pastorino52a47d42018-03-06 05:29:03257 OutputTypes(BTreeMap::from_iter(
258 entries.iter().map(|&(k, ref v)| (k, v.clone())),
259 ))
Michael Woerister32414312016-08-02 20:53:58260 }
Niko Matsakisd09fd1a2016-01-29 20:07:04261
Michael Woerister32414312016-08-02 20:53:58262 pub fn get(&self, key: &OutputType) -> Option<&Option<PathBuf>> {
263 self.0.get(key)
264 }
Niko Matsakisd09fd1a2016-01-29 20:07:04265
Michael Woerister32414312016-08-02 20:53:58266 pub fn contains_key(&self, key: &OutputType) -> bool {
267 self.0.contains_key(key)
268 }
269
Jeremy Stuckid28832d2019-06-21 21:49:03270 pub fn keys(&self) -> BTreeMapKeysIter<'_, OutputType, Option<PathBuf>> {
Michael Woerister32414312016-08-02 20:53:58271 self.0.keys()
272 }
273
Jeremy Stuckid28832d2019-06-21 21:49:03274 pub fn values(&self) -> BTreeMapValuesIter<'_, OutputType, Option<PathBuf>> {
Michael Woerister32414312016-08-02 20:53:58275 self.0.values()
276 }
Nick Cameronb059a802016-12-29 00:23:38277
varkor84145202018-03-27 23:13:34278 pub fn len(&self) -> usize {
279 self.0.len()
280 }
281
Alexander Regueiroc1d29ee2019-09-06 02:57:44282 // Returns `true` if any of the output types require codegen or linking.
Irina Popab63d7e22018-05-08 13:10:16283 pub fn should_codegen(&self) -> bool {
Nick Cameronb059a802016-12-29 00:23:38284 self.0.keys().any(|k| match *k {
Santiago Pastorino52a47d42018-03-06 05:29:03285 OutputType::Bitcode
286 | OutputType::Assembly
287 | OutputType::LlvmAssembly
288 | OutputType::Mir
289 | OutputType::Object
290 | OutputType::Exe => true,
291 OutputType::Metadata | OutputType::DepInfo => false,
Nick Cameronb059a802016-12-29 00:23:38292 })
293 }
Brian Andersonc27133e2015-01-06 14:26:08294}
295
Alexander Regueiroc1d29ee2019-09-06 02:57:44296/// Use tree-based collections to cheaply get a deterministic `Hash` implementation.
297/// *Do not* switch `BTreeMap` or `BTreeSet` out for an unsorted container type! That
298/// would break dependency tracking for command-line arguments.
Nicholas Nethercoteac6daed2019-10-20 04:54:53299#[derive(Clone)]
Aaron Hill482b77a2019-04-07 22:48:40300pub struct Externs(BTreeMap<String, ExternEntry>);
Michael Woerister32414312016-08-02 20:53:58301
Nicholas Nethercoteac6daed2019-10-20 04:54:53302#[derive(Clone, Debug, Default)]
Aaron Hill7cc3ce32019-03-25 03:06:32303pub struct ExternEntry {
Aaron Hill482b77a2019-04-07 22:48:40304 pub locations: BTreeSet<Option<String>>,
305 pub is_private_dep: bool
Aaron Hill7cc3ce32019-03-25 03:06:32306}
Aaron Hill21491dc2019-03-21 03:27:08307
Michael Woerister32414312016-08-02 20:53:58308impl Externs {
Aaron Hill482b77a2019-04-07 22:48:40309 pub fn new(data: BTreeMap<String, ExternEntry>) -> Externs {
Michael Woerister32414312016-08-02 20:53:58310 Externs(data)
311 }
312
Aaron Hill482b77a2019-04-07 22:48:40313 pub fn get(&self, key: &str) -> Option<&ExternEntry> {
Michael Woerister32414312016-08-02 20:53:58314 self.0.get(key)
315 }
316
Jeremy Stuckid28832d2019-06-21 21:49:03317 pub fn iter(&self) -> BTreeMapIter<'_, String, ExternEntry> {
Aaron Hill21491dc2019-03-21 03:27:08318 self.0.iter()
319 }
320}
321
322
Michael Woerister32414312016-08-02 20:53:58323macro_rules! hash_option {
324 ($opt_name:ident, $opt_expr:expr, $sub_hashes:expr, [UNTRACKED]) => ({});
325 ($opt_name:ident, $opt_expr:expr, $sub_hashes:expr, [TRACKED]) => ({
326 if $sub_hashes.insert(stringify!($opt_name),
Manish Goregaokarf3cb9622018-02-23 18:02:10327 $opt_expr as &dyn dep_tracking::DepTrackingHash).is_some() {
Alexander Regueiroc1d29ee2019-09-06 02:57:44328 bug!("duplicate key in CLI DepTrackingHash: {}", stringify!($opt_name))
Michael Woerister32414312016-08-02 20:53:58329 }
330 });
Michael Woerister32414312016-08-02 20:53:58331}
332
333macro_rules! top_level_options {
334 (pub struct Options { $(
335 $opt:ident : $t:ty [$dep_tracking_marker:ident $($warn_val:expr, $warn_text:expr)*],
336 )* } ) => (
337 #[derive(Clone)]
338 pub struct Options {
339 $(pub $opt: $t),*
340 }
341
342 impl Options {
343 pub fn dep_tracking_hash(&self) -> u64 {
344 let mut sub_hashes = BTreeMap::new();
345 $({
346 hash_option!($opt,
347 &self.$opt,
348 &mut sub_hashes,
349 [$dep_tracking_marker $($warn_val,
350 $warn_text,
351 self.error_format)*]);
352 })*
Alex Crichton10c31342016-09-29 00:23:36353 let mut hasher = DefaultHasher::new();
Michael Woerister32414312016-08-02 20:53:58354 dep_tracking::stable_hash(sub_hashes,
355 &mut hasher,
356 self.error_format);
357 hasher.finish()
358 }
359 }
360 );
361}
362
Alexander Regueiroc1d29ee2019-09-06 02:57:44363// The top-level command-line options struct.
Michael Woerister32414312016-08-02 20:53:58364//
365// For each option, one has to specify how it behaves with regard to the
366// dependency tracking system of incremental compilation. This is done via the
367// square-bracketed directive after the field type. The options are:
368//
369// [TRACKED]
370// A change in the given field will cause the compiler to completely clear the
371// incremental compilation cache before proceeding.
372//
373// [UNTRACKED]
374// Incremental compilation is not influenced by this option.
375//
Michael Woerister32414312016-08-02 20:53:58376// If you add a new option to this struct or one of the sub-structs like
Alexander Regueiroc1d29ee2019-09-06 02:57:44377// `CodegenOptions`, think about how it influences incremental compilation. If in
Michael Woerister32414312016-08-02 20:53:58378// doubt, specify [TRACKED], which is always "correct" but might lead to
379// unnecessary re-compilation.
380top_level_options!(
381 pub struct Options {
382 // The crate config requested for the session, which may be combined
Alexander Regueiroc1d29ee2019-09-06 02:57:44383 // with additional crate configurations during the compile process.
Michael Woerister32414312016-08-02 20:53:58384 crate_types: Vec<CrateType> [TRACKED],
385 optimize: OptLevel [TRACKED],
Alexander Regueiroc1d29ee2019-09-06 02:57:44386 // Include the `debug_assertions` flag in dependency tracking, since it
Michael Woerister32414312016-08-02 20:53:58387 // can influence whether overflow checks are done or not.
388 debug_assertions: bool [TRACKED],
Mark Rousskov2bc71972018-07-26 17:41:10389 debuginfo: DebugInfo [TRACKED],
Michael Woerister32414312016-08-02 20:53:58390 lint_opts: Vec<(String, lint::Level)> [TRACKED],
391 lint_cap: Option<lint::Level> [TRACKED],
392 describe_lints: bool [UNTRACKED],
393 output_types: OutputTypes [TRACKED],
Nicholas Nethercotef1300612018-11-22 05:33:07394 search_paths: Vec<SearchPath> [UNTRACKED],
Peter Wagenetae32b6e2017-02-21 21:18:58395 libs: Vec<(String, Option<String>, Option<cstore::NativeLibraryKind>)> [TRACKED],
Joel Galensone9e45c52019-08-12 16:34:41396 maybe_sysroot: Option<PathBuf> [UNTRACKED],
Michael Woerister32414312016-08-02 20:53:58397
Philipp Oppermann3908b2e2018-03-14 14:27:06398 target_triple: TargetTriple [TRACKED],
Michael Woerister32414312016-08-02 20:53:58399
Michael Woerister32414312016-08-02 20:53:58400 test: bool [TRACKED],
401 error_format: ErrorOutputType [UNTRACKED],
Michael Woerister32414312016-08-02 20:53:58402
Alexander Regueiroc1d29ee2019-09-06 02:57:44403 // If `Some`, enable incremental compilation, using the given
404 // directory to store intermediate results.
Michael Woerister32414312016-08-02 20:53:58405 incremental: Option<PathBuf> [UNTRACKED],
406
407 debugging_opts: DebuggingOptions [TRACKED],
408 prints: Vec<PrintRequest> [UNTRACKED],
est31c9af68e2017-11-19 22:35:53409 // Determines which borrow checker(s) to run. This is the parsed, sanitized
410 // version of `debugging_opts.borrowck`, which is just a plain string.
411 borrowck_mode: BorrowckMode [UNTRACKED],
Michael Woerister32414312016-08-02 20:53:58412 cg: CodegenOptions [TRACKED],
Alex Crichton2e9d9d42018-03-01 15:51:00413 externs: Externs [UNTRACKED],
Michael Woerister32414312016-08-02 20:53:58414 crate_name: Option<String> [TRACKED],
415 // An optional name to use as the crate for std during std injection,
Vadim Petrochenkovc6c6cf92018-03-09 15:51:48416 // written `extern crate name as std`. Defaults to `std`. Used by
Michael Woerister32414312016-08-02 20:53:58417 // out-of-tree drivers.
418 alt_std_name: Option<String> [TRACKED],
Alexander Regueiroc1d29ee2019-09-06 02:57:44419 // Indicates how the compiler should treat unstable features.
Michael Woerister32414312016-08-02 20:53:58420 unstable_features: UnstableFeatures [TRACKED],
Alex Crichton7724a042016-09-30 02:10:29421
422 // Indicates whether this run of the compiler is actually rustdoc. This
423 // is currently just a hack and will be removed eventually, so please
424 // try to not rely on this too much.
425 actually_rustdoc: bool [TRACKED],
Alex Crichton9e35b792017-09-25 19:26:25426
Alex Crichton855f6d12017-11-25 19:13:58427 // Specifications of codegen units / ThinLTO which are forced as a
428 // result of parsing command line options. These are not necessarily
429 // what rustc was invoked with, but massaged a bit to agree with
430 // commands like `--emit llvm-ir` which they're often incompatible with
431 // if we otherwise use the defaults of rustc.
Alex Crichton51877632017-10-04 21:38:52432 cli_forced_codegen_units: Option<usize> [UNTRACKED],
Alex Crichton8bde2ac2018-01-16 23:02:31433 cli_forced_thinlto_off: bool [UNTRACKED],
Jeremy Fitzhardinge56a68282018-02-18 23:05:24434
Alexander Regueiroc1d29ee2019-09-06 02:57:44435 // Remap source path prefixes in all output (messages, object files, debug, etc.).
Jeremy Fitzhardinge56a68282018-02-18 23:05:24436 remap_path_prefix: Vec<(PathBuf, PathBuf)> [UNTRACKED],
Michael Woeristera9810892018-04-25 13:45:04437
Kurtis Nusbaum320fdaa2018-04-20 04:03:21438 edition: Edition [TRACKED],
Alex Crichton17312332019-07-17 19:52:56439
Alexander Regueiroc1d29ee2019-09-06 02:57:44440 // `true` if we're emitting JSON blobs about each artifact produced
Alex Crichton17312332019-07-17 19:52:56441 // by the compiler.
442 json_artifact_notifications: bool [TRACKED],
Michael Woerister32414312016-08-02 20:53:58443 }
444);
445
Robin Kruppee3f6e682017-04-30 18:33:25446#[derive(Copy, Clone, PartialEq, Eq, Debug)]
Alex Crichton117984b2014-12-16 00:03:39447pub enum PrintRequest {
448 FileNames,
449 Sysroot,
450 CrateName,
Alex Crichtona1ffe6b2016-01-25 19:36:18451 Cfg,
Jorge Aparicio0bb42092016-02-12 15:11:58452 TargetList,
Cameron Harte1efa322016-07-10 14:22:13453 TargetCPUs,
454 TargetFeatures,
455 RelocationModels,
456 CodeModels,
Amanieu d'Antrasb233a6e2017-10-31 18:24:04457 TlsModels,
Doug Goldsteinff112642016-04-07 21:36:35458 TargetSpec,
Kornel29206582017-08-22 20:20:42459 NativeStaticLibs,
Alex Crichton117984b2014-12-16 00:03:39460}
461
Nicholas Nethercoteac6daed2019-10-20 04:54:53462#[derive(Copy, Clone)]
est31c9af68e2017-11-19 22:35:53463pub enum BorrowckMode {
est31c9af68e2017-11-19 22:35:53464 Mir,
Felix S. Klock IIa23e8a72018-07-20 15:29:29465 Migrate,
est31c9af68e2017-11-19 22:35:53466}
467
468impl BorrowckMode {
Alexander Regueiroc1d29ee2019-09-06 02:57:44469 /// Returns whether we should run the MIR-based borrow check, but also fall back
Felix S. Klock IIa23e8a72018-07-20 15:29:29470 /// on the AST borrow check if the MIR-based one errors.
471 pub fn migrate(self) -> bool {
472 match self {
Felix S. Klock IIa23e8a72018-07-20 15:29:29473 BorrowckMode::Mir => false,
474 BorrowckMode::Migrate => true,
475 }
476 }
est31c9af68e2017-11-19 22:35:53477}
478
Niko Matsakise135fa52014-11-27 12:21:26479pub enum Input {
Alexander Regueiroc1d29ee2019-09-06 02:57:44480 /// Load source code from a file.
Alex Crichton95d90462015-02-27 05:00:43481 File(PathBuf),
Alexander Regueiroc1d29ee2019-09-06 02:57:44482 /// Load source code from a string.
mitaaea7cf902016-03-10 03:49:40483 Str {
Alexander Regueiroc1d29ee2019-09-06 02:57:44484 /// A string that is shown in place of a filename.
Oliver Schneiderd732da82017-12-14 07:09:19485 name: FileName,
Alexander Regueiroc1d29ee2019-09-06 02:57:44486 /// An anonymous string containing the source code.
mitaaea7cf902016-03-10 03:49:40487 input: String,
488 },
Niko Matsakise135fa52014-11-27 12:21:26489}
490
491impl Input {
ljedrz675f00b2018-10-10 13:30:53492 pub fn filestem(&self) -> &str {
Niko Matsakise135fa52014-11-27 12:21:26493 match *self {
ljedrz675f00b2018-10-10 13:30:53494 Input::File(ref ifile) => ifile.file_stem().unwrap().to_str().unwrap(),
495 Input::Str { .. } => "rust_out",
Niko Matsakise135fa52014-11-27 12:21:26496 }
497 }
Guillaume Gomezdadfa132018-05-10 18:13:25498
499 pub fn get_input(&mut self) -> Option<&mut String> {
500 match *self {
501 Input::File(_) => None,
502 Input::Str { ref mut input, .. } => Some(input),
503 }
504 }
John Kåre Alsaker23a51f92018-12-08 19:30:23505
506 pub fn source_name(&self) -> FileName {
507 match *self {
508 Input::File(ref ifile) => ifile.clone().into(),
509 Input::Str { ref name, .. } => name.clone(),
510 }
511 }
Niko Matsakise135fa52014-11-27 12:21:26512}
513
Mark Rousskovac4439c2018-08-03 22:41:30514#[derive(Clone, Hash)]
Niko Matsakise135fa52014-11-27 12:21:26515pub struct OutputFilenames {
Alex Crichton95d90462015-02-27 05:00:43516 pub out_directory: PathBuf,
Niko Matsakise135fa52014-11-27 12:21:26517 pub out_filestem: String,
Alex Crichton95d90462015-02-27 05:00:43518 pub single_output_file: Option<PathBuf>,
Niko Matsakise135fa52014-11-27 12:21:26519 pub extra: String,
Michael Woerister32414312016-08-02 20:53:58520 pub outputs: OutputTypes,
Niko Matsakise135fa52014-11-27 12:21:26521}
522
Mark Rousskovac4439c2018-08-03 22:41:30523impl_stable_hash_via_hash!(OutputFilenames);
Michael Woerister74d6b852017-09-18 10:14:52524
Vadim Petrochenkovd588f932017-11-03 19:41:15525pub const RUST_CGU_EXT: &str = "rcgu";
Michael Woerister65e8a132016-05-14 00:48:32526
Niko Matsakise135fa52014-11-27 12:21:26527impl OutputFilenames {
Alex Crichton95d90462015-02-27 05:00:43528 pub fn path(&self, flavor: OutputType) -> PathBuf {
Santiago Pastorino52a47d42018-03-06 05:29:03529 self.outputs
530 .get(&flavor)
531 .and_then(|p| p.to_owned())
Alex Crichton8c963c02015-09-30 17:08:37532 .or_else(|| self.single_output_file.clone())
Michael Woerister65e8a132016-05-14 00:48:32533 .unwrap_or_else(|| self.temp_path(flavor, None))
Niko Matsakise135fa52014-11-27 12:21:26534 }
535
Alexander Regueiroc3e182c2019-02-08 13:53:55536 /// Gets the path where a compilation artifact of the given type for the
Michael Woerister65e8a132016-05-14 00:48:32537 /// given codegen unit should be placed on disk. If codegen_unit_name is
538 /// None, a path distinct from those of any codegen unit will be generated.
Santiago Pastorino52a47d42018-03-06 05:29:03539 pub fn temp_path(&self, flavor: OutputType, codegen_unit_name: Option<&str>) -> PathBuf {
Niko Matsakis2f9fff212016-07-25 14:51:14540 let extension = flavor.extension();
Michael Woerister65e8a132016-05-14 00:48:32541 self.temp_path_ext(extension, codegen_unit_name)
542 }
543
544 /// Like temp_path, but also supports things where there is no corresponding
Alexander Regueiroc3e182c2019-02-08 13:53:55545 /// OutputType, like noopt-bitcode or lto-bitcode.
Santiago Pastorino52a47d42018-03-06 05:29:03546 pub fn temp_path_ext(&self, ext: &str, codegen_unit_name: Option<&str>) -> PathBuf {
Alex Crichton95d90462015-02-27 05:00:43547 let base = self.out_directory.join(&self.filestem());
Michael Woerister65e8a132016-05-14 00:48:32548
549 let mut extension = String::new();
550
551 if let Some(codegen_unit_name) = codegen_unit_name {
Alex Crichton4ca1b192017-07-23 15:14:38552 extension.push_str(codegen_unit_name);
Niko Matsakise135fa52014-11-27 12:21:26553 }
Michael Woerister65e8a132016-05-14 00:48:32554
555 if !ext.is_empty() {
556 if !extension.is_empty() {
557 extension.push_str(".");
Alex Crichton4ca1b192017-07-23 15:14:38558 extension.push_str(RUST_CGU_EXT);
559 extension.push_str(".");
Michael Woerister65e8a132016-05-14 00:48:32560 }
561
562 extension.push_str(ext);
563 }
564
565 let path = base.with_extension(&extension[..]);
566 path
Niko Matsakise135fa52014-11-27 12:21:26567 }
568
Alex Crichton95d90462015-02-27 05:00:43569 pub fn with_extension(&self, extension: &str) -> PathBuf {
Santiago Pastorino52a47d42018-03-06 05:29:03570 self.out_directory
571 .join(&self.filestem())
572 .with_extension(extension)
Niko Matsakise135fa52014-11-27 12:21:26573 }
574
575 pub fn filestem(&self) -> String {
576 format!("{}{}", self.out_filestem, self.extra)
577 }
578}
579
Niko Matsakisdc6e4142014-11-16 01:30:33580pub fn host_triple() -> &'static str {
581 // Get the host triple out of the build environment. This ensures that our
582 // idea of the host triple is the same as for the set of libraries we've
583 // actually built. We can't just take LLVM's host triple because they
584 // normalize all ix86 architectures to i386.
585 //
586 // Instead of grabbing the host triple (for the current host), we grab (at
587 // compile time) the target triple that this rustc is built with and
588 // calling that (at runtime) the host triple.
Santiago Pastorino52a47d42018-03-06 05:29:03589 (option_env!("CFG_COMPILER_HOST_TRIPLE")).expect("CFG_COMPILER_HOST_TRIPLE")
Niko Matsakisdc6e4142014-11-16 01:30:33590}
591
Mark Rousskov5fcef252018-07-26 18:36:11592impl Default for Options {
593 fn default() -> Options {
594 Options {
595 crate_types: Vec::new(),
596 optimize: OptLevel::No,
597 debuginfo: DebugInfo::None,
598 lint_opts: Vec::new(),
599 lint_cap: None,
600 describe_lints: false,
601 output_types: OutputTypes(BTreeMap::new()),
Nicholas Nethercotef1300612018-11-22 05:33:07602 search_paths: vec![],
Mark Rousskov5fcef252018-07-26 18:36:11603 maybe_sysroot: None,
604 target_triple: TargetTriple::from_triple(host_triple()),
605 test: false,
606 incremental: None,
607 debugging_opts: basic_debugging_options(),
608 prints: Vec::new(),
Matthew Jasperaa6fb6c2019-01-26 17:25:37609 borrowck_mode: BorrowckMode::Migrate,
Mark Rousskov5fcef252018-07-26 18:36:11610 cg: basic_codegen_options(),
611 error_format: ErrorOutputType::default(),
612 externs: Externs(BTreeMap::new()),
613 crate_name: None,
614 alt_std_name: None,
615 libs: Vec::new(),
616 unstable_features: UnstableFeatures::Disallow,
617 debug_assertions: true,
618 actually_rustdoc: false,
619 cli_forced_codegen_units: None,
620 cli_forced_thinlto_off: false,
621 remap_path_prefix: Vec::new(),
622 edition: DEFAULT_EDITION,
Alex Crichton17312332019-07-17 19:52:56623 json_artifact_notifications: false,
Mark Rousskov5fcef252018-07-26 18:36:11624 }
Nick Cameron37ca3672014-05-06 11:38:01625 }
626}
627
Niko Matsakisfe47ca02016-03-28 21:43:36628impl Options {
Alexander Regueiroc3e182c2019-02-08 13:53:55629 /// Returns `true` if there is a reason to build the dep graph.
Niko Matsakisfe47ca02016-03-28 21:43:36630 pub fn build_dep_graph(&self) -> bool {
Santiago Pastorino52a47d42018-03-06 05:29:03631 self.incremental.is_some() || self.debugging_opts.dump_dep_graph
632 || self.debugging_opts.query_dep_graph
Niko Matsakisfe47ca02016-03-28 21:43:36633 }
Michael Woerister59cfe902016-07-13 21:03:02634
Michael Woeristerca0a4032017-06-23 14:37:12635 #[inline(always)]
636 pub fn enable_dep_node_debug_strs(&self) -> bool {
Santiago Pastorino52a47d42018-03-06 05:29:03637 cfg!(debug_assertions)
638 && (self.debugging_opts.query_dep_graph || self.debugging_opts.incremental_info)
Michael Woeristerca0a4032017-06-23 14:37:12639 }
640
Michael Woerister39ffea32017-04-24 17:01:19641 pub fn file_path_mapping(&self) -> FilePathMapping {
Jeremy Fitzhardinge56a68282018-02-18 23:05:24642 FilePathMapping::new(self.remap_path_prefix.clone())
Michael Woerister39ffea32017-04-24 17:01:19643 }
varkorc76cdce2017-12-18 15:35:45644
Alexander Regueiroc1d29ee2019-09-06 02:57:44645 /// Returns `true` if there will be an output file generated.
varkorc76cdce2017-12-18 15:35:45646 pub fn will_create_output_file(&self) -> bool {
647 !self.debugging_opts.parse_only && // The file is just being parsed
648 !self.debugging_opts.ls // The file is just being queried
649 }
Mark Rousskova9093a42018-07-26 19:20:47650
651 #[inline]
652 pub fn share_generics(&self) -> bool {
653 match self.debugging_opts.share_generics {
654 Some(setting) => setting,
655 None => {
Mark Rousskova9093a42018-07-26 19:20:47656 match self.optimize {
657 OptLevel::No |
658 OptLevel::Less |
659 OptLevel::Size |
660 OptLevel::SizeMin => true,
661 OptLevel::Default |
662 OptLevel::Aggressive => false,
663 }
664 }
665 }
666 }
Niko Matsakisfe47ca02016-03-28 21:43:36667}
668
Igor Matuszewskiff19a532019-01-13 12:06:26669// The type of entry function, so users can have their own entry functions
670#[derive(Copy, Clone, PartialEq, Hash, Debug)]
Nick Cameron37ca3672014-05-06 11:38:01671pub enum EntryFnType {
Mark Rousskov442a4742018-07-26 17:29:45672 Main,
673 Start,
Nick Cameron37ca3672014-05-06 11:38:01674}
675
Igor Matuszewskiff19a532019-01-13 12:06:26676impl_stable_hash_via_hash!(EntryFnType);
677
Alex Crichton5d531ae2019-09-16 20:34:57678#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, HashStable)]
Nick Cameron37ca3672014-05-06 11:38:01679pub enum CrateType {
Mark Rousskov2a934422018-07-26 17:13:11680 Executable,
681 Dylib,
682 Rlib,
683 Staticlib,
684 Cdylib,
685 ProcMacro,
Nick Cameron37ca3672014-05-06 11:38:01686}
687
Michael Woerister32414312016-08-02 20:53:58688#[derive(Clone, Hash)]
Keegan McAllisterad9a1da2014-09-12 15:17:58689pub enum Passes {
Mark Rousskovb3267dc2018-07-26 17:22:14690 Some(Vec<String>),
691 All,
Keegan McAllisterad9a1da2014-09-12 15:17:58692}
693
694impl Passes {
695 pub fn is_empty(&self) -> bool {
696 match *self {
Mark Rousskovb3267dc2018-07-26 17:22:14697 Passes::Some(ref v) => v.is_empty(),
698 Passes::All => false,
Keegan McAllisterad9a1da2014-09-12 15:17:58699 }
700 }
701}
702
Alexander Regueiroc1d29ee2019-09-06 02:57:44703/// Defines all `CodegenOptions`/`DebuggingOptions` fields and parsers all at once. The goal of this
Alexander Regueirofd48ca22019-09-06 20:05:37704/// macro is to define an interface that can be programmatically used by the option parser
Alexander Regueiroc1d29ee2019-09-06 02:57:44705/// to initialize the struct without hardcoding field names all over the place.
Nick Cameron37ca3672014-05-06 11:38:01706///
Alexander Regueiroc1d29ee2019-09-06 02:57:44707/// The goal is to invoke this macro once with the correct fields, and then this macro generates all
Alexander Regueirofd48ca22019-09-06 20:05:37708/// necessary code. The main gotcha of this macro is the `cgsetters` module which is a bunch of
Alexander Regueiroc1d29ee2019-09-06 02:57:44709/// generated code to parse an option into its respective field in the struct. There are a few
710/// hand-written parsers for parsing specific types of values in this module.
Manish Goregaokar3248bc52014-12-09 09:44:01711macro_rules! options {
712 ($struct_name:ident, $setter_name:ident, $defaultfn:ident,
713 $buildfn:ident, $prefix:expr, $outputname:expr,
714 $stat:ident, $mod_desc:ident, $mod_set:ident,
Michael Woerister32414312016-08-02 20:53:58715 $($opt:ident : $t:ty = (
716 $init:expr,
717 $parse:ident,
718 [$dep_tracking_marker:ident $(($dep_warn_val:expr, $dep_warn_text:expr))*],
719 $desc:expr)
720 ),* ,) =>
Nick Cameron37ca3672014-05-06 11:38:01721(
Jorge Aparicio351409a2015-01-04 03:54:18722 #[derive(Clone)]
Manish Goregaokar3248bc52014-12-09 09:44:01723 pub struct $struct_name { $(pub $opt: $t),* }
Nick Cameron37ca3672014-05-06 11:38:01724
Manish Goregaokar3248bc52014-12-09 09:44:01725 pub fn $defaultfn() -> $struct_name {
726 $struct_name { $($opt: $init),* }
Nick Cameron37ca3672014-05-06 11:38:01727 }
728
Nick Cameron82f8e5c2016-01-06 20:23:01729 pub fn $buildfn(matches: &getopts::Matches, error_format: ErrorOutputType) -> $struct_name
Manish Goregaokar3248bc52014-12-09 09:44:01730 {
731 let mut op = $defaultfn();
Jorge Apariciofd702702015-02-01 01:03:04732 for option in matches.opt_strs($prefix) {
Alex Crichtone98dce32015-04-01 18:28:34733 let mut iter = option.splitn(2, '=');
Manish Goregaokar3248bc52014-12-09 09:44:01734 let key = iter.next().unwrap();
735 let value = iter.next();
736 let option_to_lookup = key.replace("-", "_");
737 let mut found = false;
Jorge Apariciod5d7e652015-01-31 17:20:46738 for &(candidate, setter, opt_type_desc, _) in $stat {
Manish Goregaokar3248bc52014-12-09 09:44:01739 if option_to_lookup != candidate { continue }
740 if !setter(&mut op, value) {
741 match (value, opt_type_desc) {
742 (Some(..), None) => {
Nick Cameron82f8e5c2016-01-06 20:23:01743 early_error(error_format, &format!("{} option `{}` takes no \
ljedrz942a7962018-10-10 13:24:31744 value", $outputname, key))
Manish Goregaokar3248bc52014-12-09 09:44:01745 }
746 (None, Some(type_desc)) => {
Nick Cameron82f8e5c2016-01-06 20:23:01747 early_error(error_format, &format!("{0} option `{1}` requires \
ljedrz942a7962018-10-10 13:24:31748 {2} ({3} {1}=<value>)",
749 $outputname, key,
750 type_desc, $prefix))
Manish Goregaokar3248bc52014-12-09 09:44:01751 }
752 (Some(value), Some(type_desc)) => {
Nick Cameron82f8e5c2016-01-06 20:23:01753 early_error(error_format, &format!("incorrect value `{}` for {} \
ljedrz942a7962018-10-10 13:24:31754 option `{}` - {} was expected",
755 value, $outputname,
756 key, type_desc))
Manish Goregaokar3248bc52014-12-09 09:44:01757 }
Benjamin Herrdfd0e932016-03-25 17:46:11758 (None, None) => bug!()
Manish Goregaokar3248bc52014-12-09 09:44:01759 }
760 }
761 found = true;
762 break;
763 }
764 if !found {
Nick Cameron82f8e5c2016-01-06 20:23:01765 early_error(error_format, &format!("unknown {} option: `{}`",
ljedrz942a7962018-10-10 13:24:31766 $outputname, key));
Manish Goregaokar3248bc52014-12-09 09:44:01767 }
768 }
769 return op;
770 }
771
Eduard-Mihai Burtescu774724b2019-06-11 09:21:38772 impl dep_tracking::DepTrackingHash for $struct_name {
Alex Crichton10c31342016-09-29 00:23:36773 fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType) {
Michael Woerister32414312016-08-02 20:53:58774 let mut sub_hashes = BTreeMap::new();
775 $({
776 hash_option!($opt,
777 &self.$opt,
778 &mut sub_hashes,
779 [$dep_tracking_marker $($dep_warn_val,
780 $dep_warn_text,
781 error_format)*]);
782 })*
783 dep_tracking::stable_hash(sub_hashes, hasher, error_format);
784 }
785 }
786
Manish Goregaokar3248bc52014-12-09 09:44:01787 pub type $setter_name = fn(&mut $struct_name, v: Option<&str>) -> bool;
ljedrzd0c64bb2018-12-04 11:46:10788 pub const $stat: &[(&str, $setter_name, Option<&str>, &str)] =
Manish Goregaokar3248bc52014-12-09 09:44:01789 &[ $( (stringify!($opt), $mod_set::$opt, $mod_desc::$parse, $desc) ),* ];
inrustwetrust3391ddd2014-11-15 13:51:22790
Manish Goregaokar7e87ea92014-12-09 09:55:49791 #[allow(non_upper_case_globals, dead_code)]
Manish Goregaokar3248bc52014-12-09 09:44:01792 mod $mod_desc {
ljedrzd0c64bb2018-12-04 11:46:10793 pub const parse_bool: Option<&str> = None;
794 pub const parse_opt_bool: Option<&str> =
James Miller280dea72015-01-09 05:06:45795 Some("one of: `y`, `yes`, `on`, `n`, `no`, or `off`");
ljedrzd0c64bb2018-12-04 11:46:10796 pub const parse_string: Option<&str> = Some("a string");
797 pub const parse_string_push: Option<&str> = Some("a string");
798 pub const parse_pathbuf_push: Option<&str> = Some("a path");
799 pub const parse_opt_string: Option<&str> = Some("a string");
800 pub const parse_opt_pathbuf: Option<&str> = Some("a path");
801 pub const parse_list: Option<&str> = Some("a space-separated list of strings");
802 pub const parse_opt_list: Option<&str> = Some("a space-separated list of strings");
Tyler Mandryfa8fd3d2019-03-14 22:05:49803 pub const parse_opt_comma_list: Option<&str> = Some("a comma-separated list of strings");
Mark Rousskov1a1067d2019-09-30 20:27:28804 pub const parse_threads: Option<&str> = Some("a number");
ljedrzd0c64bb2018-12-04 11:46:10805 pub const parse_uint: Option<&str> = Some("a number");
806 pub const parse_passes: Option<&str> =
inrustwetrust3391ddd2014-11-15 13:51:22807 Some("a space-separated list of passes, or `all`");
ljedrzd0c64bb2018-12-04 11:46:10808 pub const parse_opt_uint: Option<&str> =
Alex Crichton117984b2014-12-16 00:03:39809 Some("a number");
ljedrzd0c64bb2018-12-04 11:46:10810 pub const parse_panic_strategy: Option<&str> =
Eric Hussb8da7192018-11-19 21:29:35811 Some("either `unwind` or `abort`");
ljedrzd0c64bb2018-12-04 11:46:10812 pub const parse_relro_level: Option<&str> =
Johannes Löthberg94b9cc92017-07-14 20:01:37813 Some("one of: `full`, `partial`, or `off`");
ljedrzd0c64bb2018-12-04 11:46:10814 pub const parse_sanitizer: Option<&str> =
Jorge Aparicio9af6aa32016-12-30 04:28:11815 Some("one of: `address`, `leak`, `memory` or `thread`");
ljedrzd0c64bb2018-12-04 11:46:10816 pub const parse_linker_flavor: Option<&str> =
Irina Popa38e96402017-12-08 19:18:21817 Some(::rustc_target::spec::LinkerFlavor::one_of());
ljedrzd0c64bb2018-12-04 11:46:10818 pub const parse_optimization_fuel: Option<&str> =
Austin Hicks63ebf082017-03-08 21:28:47819 Some("crate=integer");
ljedrzd0c64bb2018-12-04 11:46:10820 pub const parse_unpretty: Option<&str> =
Mark Mansiebfa6c72018-01-15 03:11:40821 Some("`string` or `string=string`");
Esteban Küberc41ddf12019-03-07 09:54:53822 pub const parse_treat_err_as_bug: Option<&str> =
823 Some("either no value or a number bigger than 0");
ljedrzd0c64bb2018-12-04 11:46:10824 pub const parse_lto: Option<&str> =
Michael Woerister24093a62018-09-04 15:57:17825 Some("either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, \
826 `fat`, or omitted");
Michael Woerister04f425d2019-02-01 14:15:43827 pub const parse_linker_plugin_lto: Option<&str> =
Michael Woeristerd5f8edf2018-08-02 12:16:43828 Some("either a boolean (`yes`, `no`, `on`, `off`, etc), \
Michael Woeristera9810892018-04-25 13:45:04829 or the path to the linker plugin");
Michael Woerister64ee32e2019-05-28 14:13:59830 pub const parse_switch_with_opt_path: Option<&str> =
Michael Woerister7b1df422019-04-10 11:46:37831 Some("an optional path to the profiling data output directory");
Peter Jinb91d2112018-12-31 18:58:13832 pub const parse_merge_functions: Option<&str> =
833 Some("one of: `disabled`, `trampolines`, or `aliases`");
Eduard-Mihai Burtescu20929632019-01-29 05:24:32834 pub const parse_symbol_mangling_version: Option<&str> =
835 Some("either `legacy` or `v0` (RFC 2603)");
inrustwetrust3391ddd2014-11-15 13:51:22836 }
Nick Cameron37ca3672014-05-06 11:38:01837
Manish Goregaokar7e87ea92014-12-09 09:55:49838 #[allow(dead_code)]
Manish Goregaokar3248bc52014-12-09 09:44:01839 mod $mod_set {
Eduard-Mihai Burtescu20929632019-01-29 05:24:32840 use super::{$struct_name, Passes, Sanitizer, LtoCli, LinkerPluginLto, SwitchWithOptPath,
841 SymbolManglingVersion};
Peter Jinb91d2112018-12-31 18:58:13842 use rustc_target::spec::{LinkerFlavor, MergeFunctions, PanicStrategy, RelroLevel};
Oliver Schneiderd732da82017-12-14 07:09:19843 use std::path::PathBuf;
Peter Jinb91d2112018-12-31 18:58:13844 use std::str::FromStr;
Nick Cameron37ca3672014-05-06 11:38:01845
846 $(
Manish Goregaokar3248bc52014-12-09 09:44:01847 pub fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool {
Nick Cameron37ca3672014-05-06 11:38:01848 $parse(&mut cg.$opt, v)
849 }
850 )*
851
852 fn parse_bool(slot: &mut bool, v: Option<&str>) -> bool {
853 match v {
854 Some(..) => false,
855 None => { *slot = true; true }
856 }
857 }
858
Corey Richardson6b130e32014-07-23 18:56:36859 fn parse_opt_bool(slot: &mut Option<bool>, v: Option<&str>) -> bool {
860 match v {
James Miller280dea72015-01-09 05:06:45861 Some(s) => {
862 match s {
863 "n" | "no" | "off" => {
864 *slot = Some(false);
865 }
866 "y" | "yes" | "on" => {
867 *slot = Some(true);
868 }
869 _ => { return false; }
870 }
871
872 true
873 },
Corey Richardson6b130e32014-07-23 18:56:36874 None => { *slot = Some(true); true }
875 }
876 }
877
Richo Healey55307452014-05-22 23:57:53878 fn parse_opt_string(slot: &mut Option<String>, v: Option<&str>) -> bool {
Nick Cameron37ca3672014-05-06 11:38:01879 match v {
Richo Healey1f1b2e42014-05-25 10:17:19880 Some(s) => { *slot = Some(s.to_string()); true },
Nick Cameron37ca3672014-05-06 11:38:01881 None => false,
882 }
883 }
884
Oliver Schneiderd732da82017-12-14 07:09:19885 fn parse_opt_pathbuf(slot: &mut Option<PathBuf>, v: Option<&str>) -> bool {
886 match v {
887 Some(s) => { *slot = Some(PathBuf::from(s)); true },
888 None => false,
889 }
890 }
891
Richo Healey55307452014-05-22 23:57:53892 fn parse_string(slot: &mut String, v: Option<&str>) -> bool {
Nick Cameron37ca3672014-05-06 11:38:01893 match v {
Richo Healey1f1b2e42014-05-25 10:17:19894 Some(s) => { *slot = s.to_string(); true },
Nick Cameron37ca3672014-05-06 11:38:01895 None => false,
896 }
897 }
898
Jorge Aparicio9631e9f2016-09-19 07:32:28899 fn parse_string_push(slot: &mut Vec<String>, v: Option<&str>) -> bool {
900 match v {
901 Some(s) => { slot.push(s.to_string()); true },
902 None => false,
903 }
904 }
905
Oliver Schneiderd732da82017-12-14 07:09:19906 fn parse_pathbuf_push(slot: &mut Vec<PathBuf>, v: Option<&str>) -> bool {
907 match v {
908 Some(s) => { slot.push(PathBuf::from(s)); true },
909 None => false,
910 }
911 }
912
Richo Healey55307452014-05-22 23:57:53913 fn parse_list(slot: &mut Vec<String>, v: Option<&str>)
Nick Cameron37ca3672014-05-06 11:38:01914 -> bool {
915 match v {
916 Some(s) => {
ljedrz59c8a272018-07-26 15:11:10917 slot.extend(s.split_whitespace().map(|s| s.to_string()));
Nick Cameron37ca3672014-05-06 11:38:01918 true
919 },
920 None => false,
921 }
922 }
923
Corey Richardson6b130e32014-07-23 18:56:36924 fn parse_opt_list(slot: &mut Option<Vec<String>>, v: Option<&str>)
925 -> bool {
926 match v {
927 Some(s) => {
kwantamc361e132015-04-18 17:49:51928 let v = s.split_whitespace().map(|s| s.to_string()).collect();
Corey Richardson6b130e32014-07-23 18:56:36929 *slot = Some(v);
930 true
931 },
932 None => false,
933 }
934 }
935
Tyler Mandryfa8fd3d2019-03-14 22:05:49936 fn parse_opt_comma_list(slot: &mut Option<Vec<String>>, v: Option<&str>)
937 -> bool {
938 match v {
939 Some(s) => {
940 let v = s.split(',').map(|s| s.to_string()).collect();
941 *slot = Some(v);
942 true
943 },
944 None => false,
945 }
946 }
947
Mark Rousskov1a1067d2019-09-30 20:27:28948 fn parse_threads(slot: &mut usize, v: Option<&str>) -> bool {
949 match v.and_then(|s| s.parse().ok()) {
950 Some(0) => { *slot = ::num_cpus::get(); true },
951 Some(i) => { *slot = i; true },
952 None => false
953 }
954 }
955
Alex Crichton43bfaa42015-03-26 00:06:52956 fn parse_uint(slot: &mut usize, v: Option<&str>) -> bool {
Alex Crichton0cdde6e2015-01-28 06:52:32957 match v.and_then(|s| s.parse().ok()) {
Stuart Pernsteinercf672852014-07-17 17:52:52958 Some(i) => { *slot = i; true },
959 None => false
960 }
961 }
Keegan McAllisterad9a1da2014-09-12 15:17:58962
Alex Crichton43bfaa42015-03-26 00:06:52963 fn parse_opt_uint(slot: &mut Option<usize>, v: Option<&str>) -> bool {
Alex Crichton117984b2014-12-16 00:03:39964 match v {
Alex Crichton0cdde6e2015-01-28 06:52:32965 Some(s) => { *slot = s.parse().ok(); slot.is_some() }
Alex Crichton9e35b792017-09-25 19:26:25966 None => { *slot = None; false }
Alex Crichton117984b2014-12-16 00:03:39967 }
968 }
969
Keegan McAllisterad9a1da2014-09-12 15:17:58970 fn parse_passes(slot: &mut Passes, v: Option<&str>) -> bool {
971 match v {
972 Some("all") => {
Mark Rousskovb3267dc2018-07-26 17:22:14973 *slot = Passes::All;
Keegan McAllisterad9a1da2014-09-12 15:17:58974 true
975 }
976 v => {
iirelue593c3b2016-10-29 21:54:04977 let mut passes = vec![];
Keegan McAllisterad9a1da2014-09-12 15:17:58978 if parse_list(&mut passes, v) {
Mark Rousskovb3267dc2018-07-26 17:22:14979 *slot = Passes::Some(passes);
Keegan McAllisterad9a1da2014-09-12 15:17:58980 true
981 } else {
982 false
983 }
984 }
985 }
986 }
Alex Crichton0ec321f2016-04-08 23:18:40987
Jorge Apariciocbb967f2016-09-28 02:26:08988 fn parse_panic_strategy(slot: &mut Option<PanicStrategy>, v: Option<&str>) -> bool {
Alex Crichton0ec321f2016-04-08 23:18:40989 match v {
Jorge Apariciocbb967f2016-09-28 02:26:08990 Some("unwind") => *slot = Some(PanicStrategy::Unwind),
991 Some("abort") => *slot = Some(PanicStrategy::Abort),
Alex Crichton0ec321f2016-04-08 23:18:40992 _ => return false
993 }
994 true
995 }
Jorge Aparicio9af6aa32016-12-30 04:28:11996
Johannes Löthberg94b9cc92017-07-14 20:01:37997 fn parse_relro_level(slot: &mut Option<RelroLevel>, v: Option<&str>) -> bool {
998 match v {
Johannes Löthberg2161fb22017-07-17 23:27:55999 Some(s) => {
1000 match s.parse::<RelroLevel>() {
1001 Ok(level) => *slot = Some(level),
1002 _ => return false
1003 }
1004 },
Johannes Löthberg94b9cc92017-07-14 20:01:371005 _ => return false
1006 }
1007 true
1008 }
1009
Jorge Aparicio9af6aa32016-12-30 04:28:111010 fn parse_sanitizer(slote: &mut Option<Sanitizer>, v: Option<&str>) -> bool {
1011 match v {
1012 Some("address") => *slote = Some(Sanitizer::Address),
1013 Some("leak") => *slote = Some(Sanitizer::Leak),
1014 Some("memory") => *slote = Some(Sanitizer::Memory),
1015 Some("thread") => *slote = Some(Sanitizer::Thread),
1016 _ => return false,
1017 }
1018 true
1019 }
Jorge Aparicio9d11b082017-02-21 19:47:151020
1021 fn parse_linker_flavor(slote: &mut Option<LinkerFlavor>, v: Option<&str>) -> bool {
1022 match v.and_then(LinkerFlavor::from_str) {
1023 Some(lf) => *slote = Some(lf),
1024 _ => return false,
1025 }
1026 true
1027 }
Austin Hicks63ebf082017-03-08 21:28:471028
1029 fn parse_optimization_fuel(slot: &mut Option<(String, u64)>, v: Option<&str>) -> bool {
1030 match v {
1031 None => false,
1032 Some(s) => {
1033 let parts = s.split('=').collect::<Vec<_>>();
1034 if parts.len() != 2 { return false; }
1035 let crate_name = parts[0].to_string();
1036 let fuel = parts[1].parse::<u64>();
1037 if fuel.is_err() { return false; }
1038 *slot = Some((crate_name, fuel.unwrap()));
1039 true
1040 }
1041 }
1042 }
Mark Mansiebfa6c72018-01-15 03:11:401043
1044 fn parse_unpretty(slot: &mut Option<String>, v: Option<&str>) -> bool {
1045 match v {
1046 None => false,
1047 Some(s) if s.split('=').count() <= 2 => {
1048 *slot = Some(s.to_string());
1049 true
1050 }
1051 _ => false,
1052 }
1053 }
Alex Crichton8bde2ac2018-01-16 23:02:311054
Esteban Küberc41ddf12019-03-07 09:54:531055 fn parse_treat_err_as_bug(slot: &mut Option<usize>, v: Option<&str>) -> bool {
1056 match v {
1057 Some(s) => { *slot = s.parse().ok().filter(|&x| x != 0); slot.unwrap_or(0) != 0 }
1058 None => { *slot = Some(1); true }
1059 }
1060 }
1061
Michael Woerister24093a62018-09-04 15:57:171062 fn parse_lto(slot: &mut LtoCli, v: Option<&str>) -> bool {
1063 if v.is_some() {
1064 let mut bool_arg = None;
1065 if parse_opt_bool(&mut bool_arg, v) {
1066 *slot = if bool_arg.unwrap() {
1067 LtoCli::Yes
1068 } else {
1069 LtoCli::No
1070 };
1071 return true
1072 }
1073 }
1074
Alex Crichton8bde2ac2018-01-16 23:02:311075 *slot = match v {
Michael Woerister24093a62018-09-04 15:57:171076 None => LtoCli::NoParam,
1077 Some("thin") => LtoCli::Thin,
1078 Some("fat") => LtoCli::Fat,
Alex Crichton8bde2ac2018-01-16 23:02:311079 Some(_) => return false,
1080 };
1081 true
1082 }
Manish Goregaokar2cff1232018-02-04 16:52:261083
Michael Woerister04f425d2019-02-01 14:15:431084 fn parse_linker_plugin_lto(slot: &mut LinkerPluginLto, v: Option<&str>) -> bool {
Michael Woeristera9810892018-04-25 13:45:041085 if v.is_some() {
1086 let mut bool_arg = None;
1087 if parse_opt_bool(&mut bool_arg, v) {
1088 *slot = if bool_arg.unwrap() {
Michael Woerister04f425d2019-02-01 14:15:431089 LinkerPluginLto::LinkerPluginAuto
Michael Woeristera9810892018-04-25 13:45:041090 } else {
Michael Woerister04f425d2019-02-01 14:15:431091 LinkerPluginLto::Disabled
Michael Woeristera9810892018-04-25 13:45:041092 };
1093 return true
1094 }
1095 }
1096
1097 *slot = match v {
Michael Woerister04f425d2019-02-01 14:15:431098 None => LinkerPluginLto::LinkerPluginAuto,
1099 Some(path) => LinkerPluginLto::LinkerPlugin(PathBuf::from(path)),
Michael Woeristera9810892018-04-25 13:45:041100 };
1101 true
1102 }
Peter Jinb91d2112018-12-31 18:58:131103
Michael Woerister64ee32e2019-05-28 14:13:591104 fn parse_switch_with_opt_path(slot: &mut SwitchWithOptPath, v: Option<&str>) -> bool {
Michael Woerister7b1df422019-04-10 11:46:371105 *slot = match v {
Michael Woerister64ee32e2019-05-28 14:13:591106 None => SwitchWithOptPath::Enabled(None),
1107 Some(path) => SwitchWithOptPath::Enabled(Some(PathBuf::from(path))),
Michael Woerister7b1df422019-04-10 11:46:371108 };
1109 true
1110 }
1111
Peter Jinb91d2112018-12-31 18:58:131112 fn parse_merge_functions(slot: &mut Option<MergeFunctions>, v: Option<&str>) -> bool {
1113 match v.and_then(|s| MergeFunctions::from_str(s).ok()) {
1114 Some(mergefunc) => *slot = Some(mergefunc),
1115 _ => return false,
1116 }
1117 true
1118 }
Eduard-Mihai Burtescu20929632019-01-29 05:24:321119
1120 fn parse_symbol_mangling_version(
1121 slot: &mut SymbolManglingVersion,
1122 v: Option<&str>,
1123 ) -> bool {
1124 *slot = match v {
1125 Some("legacy") => SymbolManglingVersion::Legacy,
1126 Some("v0") => SymbolManglingVersion::V0,
1127 _ => return false,
1128 };
1129 true
1130 }
Nick Cameron37ca3672014-05-06 11:38:011131 }
Patrick Waltonddb24662014-11-14 17:18:101132) }
Nick Cameron37ca3672014-05-06 11:38:011133
Manish Goregaokar3248bc52014-12-09 09:44:011134options! {CodegenOptions, CodegenSetter, basic_codegen_options,
ljedrz942a7962018-10-10 13:24:311135 build_codegen_options, "C", "codegen",
1136 CG_OPTIONS, cg_type_desc, cgsetters,
Michael Woerister32414312016-08-02 20:53:581137 ar: Option<String> = (None, parse_opt_string, [UNTRACKED],
Vadim Petrochenkovb434c842017-10-08 08:41:121138 "this option is deprecated and does nothing"),
Oliver Schneiderd732da82017-12-14 07:09:191139 linker: Option<PathBuf> = (None, parse_opt_pathbuf, [UNTRACKED],
Nick Cameron37ca3672014-05-06 11:38:011140 "system linker to link outputs with"),
Jorge Aparicio9631e9f2016-09-19 07:32:281141 link_arg: Vec<String> = (vec![], parse_string_push, [UNTRACKED],
Jorge Aparicio94d2c432017-05-13 13:21:241142 "a single extra argument to append to the linker invocation (can be used several times)"),
Michael Woerister32414312016-08-02 20:53:581143 link_args: Option<Vec<String>> = (None, parse_opt_list, [UNTRACKED],
Jorge Aparicio94d2c432017-05-13 13:21:241144 "extra arguments to append to the linker invocation (space separated)"),
Michael Woerister32414312016-08-02 20:53:581145 link_dead_code: bool = (false, parse_bool, [UNTRACKED],
Johan Lorenzo39c2d852016-02-15 16:44:061146 "don't let linker strip dead code (turning it on can be used for code coverage)"),
Michael Woerister24093a62018-09-04 15:57:171147 lto: LtoCli = (LtoCli::Unspecified, parse_lto, [TRACKED],
Colin Davidsona7a1bf82014-09-21 04:36:171148 "perform LLVM link-time optimizations"),
Michael Woerister32414312016-08-02 20:53:581149 target_cpu: Option<String> = (None, parse_opt_string, [TRACKED],
Samy Kacimi66815c62019-07-23 19:26:011150 "select target processor (`rustc --print target-cpus` for details)"),
Matthias Krügerede1f7d2018-08-23 08:14:521151 target_feature: String = (String::new(), parse_string, [TRACKED],
togiberlinde3fd022019-09-04 12:53:471152 "target specific attributes. (`rustc --print target-features` for details). \
1153 This feature is unsafe."),
Michael Woerister32414312016-08-02 20:53:581154 passes: Vec<String> = (Vec::new(), parse_list, [TRACKED],
Nick Cameron37ca3672014-05-06 11:38:011155 "a list of extra LLVM passes to run (space separated)"),
Michael Woerister32414312016-08-02 20:53:581156 llvm_args: Vec<String> = (Vec::new(), parse_list, [TRACKED],
Brian Andersonc03077b2019-08-07 21:51:491157 "a list of arguments to pass to LLVM (space separated)"),
Michael Woerister0d675102019-05-28 15:27:461158 save_temps: bool = (false, parse_bool, [UNTRACKED],
Nick Cameron37ca3672014-05-06 11:38:011159 "save all temporary output files during compilation"),
Michael Woerister32414312016-08-02 20:53:581160 rpath: bool = (false, parse_bool, [UNTRACKED],
Alex Crichtona0546de2014-06-11 21:52:381161 "set rpath values in libs/exes"),
Nathan Froydffc6ddd2017-02-17 21:00:081162 overflow_checks: Option<bool> = (None, parse_opt_bool, [TRACKED],
1163 "use overflow checks for integer arithmetic"),
Michael Woerister32414312016-08-02 20:53:581164 no_prepopulate_passes: bool = (false, parse_bool, [TRACKED],
Nick Cameron37ca3672014-05-06 11:38:011165 "don't pre-populate the pass manager with a list of passes"),
Michael Woerister32414312016-08-02 20:53:581166 no_vectorize_loops: bool = (false, parse_bool, [TRACKED],
Nick Cameron37ca3672014-05-06 11:38:011167 "don't run the loop vectorization optimization passes"),
Michael Woerister32414312016-08-02 20:53:581168 no_vectorize_slp: bool = (false, parse_bool, [TRACKED],
Nick Cameron37ca3672014-05-06 11:38:011169 "don't run LLVM's SLP vectorization pass"),
Michael Woerister32414312016-08-02 20:53:581170 soft_float: bool = (false, parse_bool, [TRACKED],
James Duleyffdd9822016-09-04 12:47:251171 "use soft float ABI (*eabihf targets only)"),
Michael Woerister32414312016-08-02 20:53:581172 prefer_dynamic: bool = (false, parse_bool, [TRACKED],
Nick Cameron37ca3672014-05-06 11:38:011173 "prefer dynamic linking to static linking"),
Michael Woerister32414312016-08-02 20:53:581174 no_integrated_as: bool = (false, parse_bool, [TRACKED],
Nick Cameron37ca3672014-05-06 11:38:011175 "use an external assembler rather than LLVM's integrated one"),
Michael Woerister32414312016-08-02 20:53:581176 no_redzone: Option<bool> = (None, parse_opt_bool, [TRACKED],
John Kåre Alsaker036b9e82014-07-16 11:35:501177 "disable the use of the redzone"),
Michael Woerister32414312016-08-02 20:53:581178 relocation_model: Option<String> = (None, parse_opt_string, [TRACKED],
Samy Kacimi66815c62019-07-23 19:26:011179 "choose the relocation model to use (`rustc --print relocation-models` for details)"),
Michael Woerister32414312016-08-02 20:53:581180 code_model: Option<String> = (None, parse_opt_string, [TRACKED],
Samy Kacimi66815c62019-07-23 19:26:011181 "choose the code model to use (`rustc --print code-models` for details)"),
Michael Woerister32414312016-08-02 20:53:581182 metadata: Vec<String> = (Vec::new(), parse_list, [TRACKED],
ljedrz942a7962018-10-10 13:24:311183 "metadata to mangle symbol names with"),
Matthias Krügerede1f7d2018-08-23 08:14:521184 extra_filename: String = (String::new(), parse_string, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311185 "extra data to put in each output filename"),
Alex Crichton9e35b792017-09-25 19:26:251186 codegen_units: Option<usize> = (None, parse_opt_uint, [UNTRACKED],
Stuart Pernsteinercf672852014-07-17 17:52:521187 "divide crate into N units to optimize in parallel"),
Mark Rousskovb3267dc2018-07-26 17:22:141188 remark: Passes = (Passes::Some(Vec::new()), parse_passes, [UNTRACKED],
Keegan McAllisterad9a1da2014-09-12 15:17:581189 "print remarks for these optimization passes (space separated, or \"all\")"),
Michael Woerister32414312016-08-02 20:53:581190 no_stack_check: bool = (false, parse_bool, [UNTRACKED],
Samy Kacimi66815c62019-07-23 19:26:011191 "the `--no-stack-check` flag is deprecated and does nothing"),
Michael Woerister32414312016-08-02 20:53:581192 debuginfo: Option<usize> = (None, parse_opt_uint, [TRACKED],
Alex Crichton117984b2014-12-16 00:03:391193 "debug info emission level, 0 = no debug info, 1 = line tables only, \
1194 2 = full debug info with variable and type information"),
Michael Woerister32414312016-08-02 20:53:581195 opt_level: Option<String> = (None, parse_opt_string, [TRACKED],
Brandon Edensb1337d32016-03-27 19:42:471196 "optimize with possible levels 0-3, s, or z"),
Simonas Kazlauskas09d2db42018-03-06 18:27:191197 force_frame_pointers: Option<bool> = (None, parse_opt_bool, [TRACKED],
1198 "force use of the frame pointers"),
Michael Woerister32414312016-08-02 20:53:581199 debug_assertions: Option<bool> = (None, parse_opt_bool, [TRACKED],
Alex Crichtond5d83452015-03-02 22:51:241200 "explicitly enable the cfg(debug_assertions) directive"),
Michael Woerister32414312016-08-02 20:53:581201 inline_threshold: Option<usize> = (None, parse_opt_uint, [TRACKED],
oyvindlnedf16222017-09-13 18:11:021202 "set the threshold for inlining a function (default: 225)"),
Jorge Apariciocbb967f2016-09-28 02:26:081203 panic: Option<PanicStrategy> = (None, parse_panic_strategy,
Michael Woerister32414312016-08-02 20:53:581204 [TRACKED], "panic strategy to compile crate with"),
Michael Woerister796264b2017-12-15 20:03:481205 incremental: Option<String> = (None, parse_opt_string, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311206 "enable incremental compilation"),
Alex Crichton6f4b3782018-09-29 18:03:591207 default_linker_libraries: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311208 "allow the linker to link its default libraries"),
David Wood9536d042018-11-29 21:00:091209 linker_flavor: Option<LinkerFlavor> = (None, parse_linker_flavor, [UNTRACKED],
Brian Andersonc03077b2019-08-07 21:51:491210 "linker flavor"),
Michael Woerister04f425d2019-02-01 14:15:431211 linker_plugin_lto: LinkerPluginLto = (LinkerPluginLto::Disabled,
1212 parse_linker_plugin_lto, [TRACKED],
1213 "generate build artifacts that are compatible with linker-based LTO."),
Michael Woeristerb7fe2ca2019-05-28 14:48:031214 profile_generate: SwitchWithOptPath = (SwitchWithOptPath::Disabled,
1215 parse_switch_with_opt_path, [TRACKED],
1216 "compile the program with profiling instrumentation"),
1217 profile_use: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
1218 "use the given `.profdata` file for profile-guided optimization"),
Patrick Waltonddb24662014-11-14 17:18:101219}
Nick Cameron37ca3672014-05-06 11:38:011220
Manish Goregaokar7e87ea92014-12-09 09:55:491221options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
ljedrz942a7962018-10-10 13:24:311222 build_debugging_options, "Z", "debugging",
1223 DB_OPTIONS, db_type_desc, dbsetters,
bjorn374c92c52017-10-30 17:42:211224 codegen_backend: Option<String> = (None, parse_opt_string, [TRACKED],
1225 "the backend to use"),
Michael Woerister32414312016-08-02 20:53:581226 verbose: bool = (false, parse_bool, [UNTRACKED],
Manish Goregaokar7e87ea92014-12-09 09:55:491227 "in general, enable more debug printouts"),
Felix S. Klock II20df0e92017-03-16 13:41:481228 span_free_formats: bool = (false, parse_bool, [UNTRACKED],
1229 "when debug-printing compiler state, do not include spans"), // o/w tests have closure@path
Felix S. Klock II609813b2017-03-23 10:08:081230 identify_regions: bool = (false, parse_bool, [UNTRACKED],
1231 "make unnamed regions display as '# (where # is some non-ident unique id)"),
est31c9af68e2017-11-19 22:35:531232 borrowck: Option<String> = (None, parse_opt_string, [UNTRACKED],
Christopher Vittaldb6f7a92019-05-03 21:34:171233 "select which borrowck is used (`mir` or `migrate`)"),
Michael Woerister32414312016-08-02 20:53:581234 time_passes: bool = (false, parse_bool, [UNTRACKED],
Manish Goregaokar7e87ea92014-12-09 09:55:491235 "measure time of each rustc pass"),
John Kåre Alsakere842f572019-02-13 12:11:501236 time: bool = (false, parse_bool, [UNTRACKED],
1237 "measure time of rustc processes"),
Michael Woerister0d675102019-05-28 15:27:461238 time_llvm_passes: bool = (false, parse_bool, [UNTRACKED],
Manish Goregaokar7e87ea92014-12-09 09:55:491239 "measure time of each LLVM pass"),
Michael Woerister32414312016-08-02 20:53:581240 input_stats: bool = (false, parse_bool, [UNTRACKED],
Nick Cameronf7dc9172015-11-11 05:26:141241 "gather statistics about the input"),
Michael Woerister32414312016-08-02 20:53:581242 asm_comments: bool = (false, parse_bool, [TRACKED],
Manish Goregaokar7e87ea92014-12-09 09:55:491243 "generate comments into the assembly (may change behavior)"),
Nikita Popov22cf8332018-06-12 19:05:371244 verify_llvm_ir: bool = (false, parse_bool, [TRACKED],
1245 "verify LLVM IR"),
Michael Woerister32414312016-08-02 20:53:581246 borrowck_stats: bool = (false, parse_bool, [UNTRACKED],
Manish Goregaokar7e87ea92014-12-09 09:55:491247 "gather borrowck statistics"),
Michael Woerister32414312016-08-02 20:53:581248 no_landing_pads: bool = (false, parse_bool, [TRACKED],
Manish Goregaokar7e87ea92014-12-09 09:55:491249 "omit landing pads for unwinding"),
Simonas Kazlauskasb7195782018-01-04 20:19:231250 fewer_names: bool = (false, parse_bool, [TRACKED],
1251 "reduce memory use by retaining fewer names within compilation artifacts (LLVM-IR)"),
Michael Woerister32414312016-08-02 20:53:581252 meta_stats: bool = (false, parse_bool, [UNTRACKED],
Manish Goregaokar7e87ea92014-12-09 09:55:491253 "gather metadata statistics"),
Michael Woerister32414312016-08-02 20:53:581254 print_link_args: bool = (false, parse_bool, [UNTRACKED],
Nick Cameronf7dc9172015-11-11 05:26:141255 "print the arguments passed to the linker"),
Michael Woerister32414312016-08-02 20:53:581256 print_llvm_passes: bool = (false, parse_bool, [UNTRACKED],
Brian Andersonc03077b2019-08-07 21:51:491257 "prints the LLVM optimization passes being run"),
Michael Woerister32414312016-08-02 20:53:581258 ast_json: bool = (false, parse_bool, [UNTRACKED],
Nick Cameronf7dc9172015-11-11 05:26:141259 "print the AST as JSON and halt"),
Mark Rousskov1a1067d2019-09-30 20:27:281260 // We default to 1 here since we want to behave like
1261 // a sequential compiler for now. This'll likely be adjusted
1262 // in the future. Note that -Zthreads=0 is the way to get
1263 // the num_cpus behavior.
1264 threads: usize = (1, parse_threads, [UNTRACKED],
John Kåre Alsaker975eb312019-01-28 14:51:471265 "use a thread pool with N threads"),
Michael Woerister32414312016-08-02 20:53:581266 ast_json_noexpand: bool = (false, parse_bool, [UNTRACKED],
Nick Cameronf7dc9172015-11-11 05:26:141267 "print the pre-expansion AST as JSON and halt"),
Michael Woerister32414312016-08-02 20:53:581268 ls: bool = (false, parse_bool, [UNTRACKED],
Nick Cameronf7dc9172015-11-11 05:26:141269 "list the symbols defined by a library crate"),
Michael Woerister32414312016-08-02 20:53:581270 save_analysis: bool = (false, parse_bool, [UNTRACKED],
Nick Cameron377be7a2016-08-30 04:40:441271 "write syntax and type analysis (in JSON format) information, in \
Nick Cameroncbafc572016-08-29 00:24:551272 addition to normal output"),
Michael Woerister32414312016-08-02 20:53:581273 print_region_graph: bool = (false, parse_bool, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311274 "prints region inference graph. \
1275 Use with RUST_REGION_GRAPH=help for more info"),
Michael Woerister32414312016-08-02 20:53:581276 parse_only: bool = (false, parse_bool, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311277 "parse only; do not compile, assemble, or link"),
John Kåre Alsakerc3c1c8d2019-01-13 08:18:371278 dual_proc_macros: bool = (false, parse_bool, [TRACKED],
1279 "load proc macros for both target and host, but only link to the target"),
Irina Popab63d7e22018-05-08 13:10:161280 no_codegen: bool = (false, parse_bool, [TRACKED],
ljedrz942a7962018-10-10 13:24:311281 "run all passes except codegen; no output"),
Esteban Küberc41ddf12019-03-07 09:54:531282 treat_err_as_bug: Option<usize> = (None, parse_treat_err_as_bug, [TRACKED],
Esteban Kübere3299f22019-03-07 19:18:051283 "treat error number `val` that occurs as bug"),
Oliver Schneider56c90772018-07-19 15:53:441284 report_delayed_bugs: bool = (false, parse_bool, [TRACKED],
ljedrz942a7962018-10-10 13:24:311285 "immediately print bugs registered with `delay_span_bug`"),
Alex Burkab34a7ff2017-11-20 18:03:201286 external_macro_backtrace: bool = (false, parse_bool, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311287 "show macro backtraces even for non-local macros"),
Esteban Küber482f7f12018-01-23 19:34:571288 teach: bool = (false, parse_bool, [TRACKED],
ljedrz942a7962018-10-10 13:24:311289 "show extended diagnostic help"),
Esteban Küber21f2e932019-08-15 00:57:281290 terminal_width: Option<usize> = (None, parse_opt_uint, [UNTRACKED],
1291 "set the current terminal width"),
Tyler Mandry3f0254e2019-09-20 02:33:381292 panic_abort_tests: bool = (false, parse_bool, [TRACKED],
1293 "support compiling tests with panic=abort"),
Michael Woerister32414312016-08-02 20:53:581294 continue_parse_after_error: bool = (false, parse_bool, [TRACKED],
ljedrz942a7962018-10-10 13:24:311295 "attempt to recover from parse errors (experimental)"),
John Kåre Alsakerf0b15f62019-02-10 23:03:511296 dep_tasks: bool = (false, parse_bool, [UNTRACKED],
1297 "print tasks that execute and the color their dep node gets (requires debug build)"),
Michael Woerister32414312016-08-02 20:53:581298 incremental: Option<String> = (None, parse_opt_string, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311299 "enable incremental compilation (experimental)"),
Michael Woeristercb1ff242017-11-16 16:13:391300 incremental_queries: bool = (true, parse_bool, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311301 "enable incremental compilation support for queries (experimental)"),
Michael Woerister32414312016-08-02 20:53:581302 incremental_info: bool = (false, parse_bool, [UNTRACKED],
Niko Matsakisd4bd0542016-08-06 00:12:021303 "print high-level information about incremental reuse (or the lack thereof)"),
Niko Matsakis57ffda62016-12-01 17:29:281304 incremental_dump_hash: bool = (false, parse_bool, [UNTRACKED],
1305 "dump hash information in textual format to stdout"),
Michael Woerister3c6f6202017-11-07 14:22:291306 incremental_verify_ich: bool = (false, parse_bool, [UNTRACKED],
1307 "verify incr. comp. hashes of green query instances"),
Michael Woeristerc5dd9f52017-12-04 11:47:161308 incremental_ignore_spans: bool = (false, parse_bool, [UNTRACKED],
1309 "ignore spans during ICH computation -- used for testing"),
Jun Wu31a50662018-12-30 19:59:031310 instrument_mcount: bool = (false, parse_bool, [TRACKED],
1311 "insert function instrument code for mcount-based tracing"),
Michael Woerister32414312016-08-02 20:53:581312 dump_dep_graph: bool = (false, parse_bool, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311313 "dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv)"),
Michael Woerister32414312016-08-02 20:53:581314 query_dep_graph: bool = (false, parse_bool, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311315 "enable queries of the dependency graph for regression testing"),
Michael Woerister32414312016-08-02 20:53:581316 no_analysis: bool = (false, parse_bool, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311317 "parse and expand the source, but run no analysis"),
Michael Woerister32414312016-08-02 20:53:581318 extra_plugins: Vec<String> = (Vec::new(), parse_list, [TRACKED],
Manish Goregaokarc41cafb2014-12-09 17:25:371319 "load extra plugins"),
Michael Woerister32414312016-08-02 20:53:581320 unstable_options: bool = (false, parse_bool, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311321 "adds unstable command line options to rustc interface"),
Michael Woerister32414312016-08-02 20:53:581322 force_overflow_checks: Option<bool> = (None, parse_opt_bool, [TRACKED],
ljedrz942a7962018-10-10 13:24:311323 "force overflow checks on or off"),
Michael Woerister32414312016-08-02 20:53:581324 trace_macros: bool = (false, parse_bool, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311325 "for every macro invocation, print its name and arguments"),
Vadim Chugunovcf646112016-08-25 02:34:311326 debug_macros: bool = (false, parse_bool, [TRACKED],
ljedrz942a7962018-10-10 13:24:311327 "emit line numbers debug info inside macros"),
Michael Woerister32414312016-08-02 20:53:581328 keep_hygiene_data: bool = (false, parse_bool, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311329 "don't clear the hygiene data after analysis"),
Michael Woerister32414312016-08-02 20:53:581330 keep_ast: bool = (false, parse_bool, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311331 "keep the AST after lowering it to HIR"),
Michael Woerister32414312016-08-02 20:53:581332 show_span: Option<String> = (None, parse_opt_string, [TRACKED],
ljedrz942a7962018-10-10 13:24:311333 "show spans for compiler debugging (expr|pat|ty)"),
Felix S. Klock II9383fcf2016-11-14 16:46:201334 print_type_sizes: bool = (false, parse_bool, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311335 "print layout information for each type encountered"),
Irina Popab63d7e22018-05-08 13:10:161336 print_mono_items: Option<String> = (None, parse_opt_string, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311337 "print the result of the monomorphization collection pass"),
Ulrik Sverdrup6d46a212016-12-11 20:16:011338 mir_opt_level: usize = (1, parse_uint, [TRACKED],
ljedrz942a7962018-10-10 13:24:311339 "set the MIR optimization level (0-3, default: 1)"),
Nikita Popov12308132018-05-14 13:20:511340 mutable_noalias: Option<bool> = (None, parse_opt_bool, [TRACKED],
Josh Stone8bb5c122019-10-04 23:53:181341 "emit noalias metadata for mutable references (default: no)"),
Michael Woerister32414312016-08-02 20:53:581342 dump_mir: Option<String> = (None, parse_opt_string, [UNTRACKED],
Edd Barrett5f9f05d2018-12-07 14:48:161343 "dump MIR state to file.
1344 `val` is used to select which passes and functions to dump. For example:
1345 `all` matches all passes and functions,
1346 `foo` matches all passes for functions whose name contains 'foo',
1347 `foo & ConstProp` only the 'ConstProp' pass for function names containing 'foo',
1348 `foo | bar` all passes for function names containing 'foo' or 'bar'."),
1349
varkor2ccc82e2018-01-14 20:02:071350 dump_mir_dir: String = (String::from("mir_dump"), parse_string, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311351 "the directory the MIR is dumped into"),
Mikhail Modin08b1fe32017-10-24 11:48:391352 dump_mir_graphviz: bool = (false, parse_bool, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311353 "in addition to `.mir` files, create graphviz `.dot` files"),
Niko Matsakis46b342f2017-04-25 22:23:331354 dump_mir_exclude_pass_number: bool = (false, parse_bool, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311355 "if set, exclude the pass number when dumping MIR (used in tests)"),
Ralf Jungaafcf2c2018-10-24 09:47:171356 mir_emit_retag: bool = (false, parse_bool, [TRACKED],
Alexander Regueiroee89c082018-11-27 02:59:491357 "emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0"),
Michael Woeristerdd65cb22016-08-23 17:23:581358 perf_stats: bool = (false, parse_bool, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311359 "print some performance-related statistics"),
John Kåre Alsaker0257c5a2018-12-24 05:18:391360 query_stats: bool = (false, parse_bool, [UNTRACKED],
1361 "print some statistics about the query system"),
Michael Woerister94e655e2016-11-04 15:37:391362 hir_stats: bool = (false, parse_bool, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311363 "print some statistics about AST and HIR"),
Oliver Schneider87a9ae22016-12-07 12:22:211364 always_encode_mir: bool = (false, parse_bool, [TRACKED],
ljedrz942a7962018-10-10 13:24:311365 "encode MIR of all functions into the crate metadata"),
Oliver Scherer39b21372019-03-25 10:16:581366 json_rendered: Option<String> = (None, parse_opt_string, [UNTRACKED],
1367 "describes how to render the `rendered` field of json diagnostics"),
Oliver Schererd0129a62018-11-21 09:54:461368 unleash_the_miri_inside_of_you: bool = (false, parse_bool, [TRACKED],
1369 "take the breaks off const evaluation. NOTE: this is unsound"),
Dylan MacKenziebc7928a2019-09-24 04:33:581370 suppress_const_validation_back_compat_ice: bool = (false, parse_bool, [TRACKED],
1371 "silence ICE triggered when the new const validator disagrees with the old"),
Alex Crichton1b8e6c12016-12-17 22:11:021372 osx_rpath_install_name: bool = (false, parse_bool, [TRACKED],
ljedrz942a7962018-10-10 13:24:311373 "pass `-install_name @rpath/...` to the macOS linker"),
Jorge Aparicio0b06db52017-02-21 03:34:421374 sanitizer: Option<Sanitizer> = (None, parse_sanitizer, [TRACKED],
Brian Andersonc03077b2019-08-07 21:51:491375 "use a sanitizer"),
Austin Hicks63ebf082017-03-08 21:28:471376 fuel: Option<(String, u64)> = (None, parse_optimization_fuel, [TRACKED],
oyvindlne89748e2017-09-13 20:50:471377 "set the optimization fuel quota for a crate"),
Austin Hicks63ebf082017-03-08 21:28:471378 print_fuel: Option<String> = (None, parse_opt_string, [TRACKED],
Brian Andersonc03077b2019-08-07 21:51:491379 "make rustc print the total optimization fuel used by a crate"),
Alex Crichton99f629a2017-05-08 20:36:261380 force_unstable_if_unmarked: bool = (false, parse_bool, [TRACKED],
1381 "force all crates to be `rustc_private` unstable"),
Jorge Aparicio94d2c432017-05-13 13:21:241382 pre_link_arg: Vec<String> = (vec![], parse_string_push, [UNTRACKED],
1383 "a single extra argument to prepend the linker invocation (can be used several times)"),
1384 pre_link_args: Option<Vec<String>> = (None, parse_opt_list, [UNTRACKED],
1385 "extra arguments to prepend to the linker invocation (space separated)"),
whitequark42754ce2017-02-13 09:57:501386 profile: bool = (false, parse_bool, [TRACKED],
1387 "insert profiling code"),
ljedrz942a7962018-10-10 13:24:311388 disable_instrumentation_preinliner: bool = (false, parse_bool, [TRACKED],
1389 "Disable the instrumentation pre-inliner, useful for profiling / PGO."),
Johannes Löthberg6a8328c2017-07-17 22:18:001390 relro_level: Option<RelroLevel> = (None, parse_relro_level, [TRACKED],
1391 "choose which RELRO level to use"),
Niko Matsakiseaac10e2018-05-01 14:49:111392 nll_facts: bool = (false, parse_bool, [UNTRACKED],
1393 "dump facts from NLL analysis into side files"),
Felix S. Klock II173315e2018-05-04 10:05:101394 nll_dont_emit_read_for_match: bool = (false, parse_bool, [UNTRACKED],
Remy Rakicf5e31052018-09-14 19:05:311395 "in match codegen, do not include FakeRead statements (used by mir-borrowck)"),
Felix S. Klock II82e17502018-09-15 04:27:551396 dont_buffer_diagnostics: bool = (false, parse_bool, [UNTRACKED],
1397 "emit diagnostics rather than buffering (breaks NLL error downgrading, sorting)."),
Douglas Campos4f882832018-05-25 22:17:041398 polonius: bool = (false, parse_bool, [UNTRACKED],
1399 "enable polonius-based borrow-checker"),
Irina Popab63d7e22018-05-08 13:10:161400 codegen_time_graph: bool = (false, parse_bool, [UNTRACKED],
1401 "generate a graphical HTML report of time spent in codegen and LLVM"),
Alex Crichton855f6d12017-11-25 19:13:581402 thinlto: Option<bool> = (None, parse_opt_bool, [TRACKED],
Alex Crichton4ca1b192017-07-23 15:14:381403 "enable ThinLTO when possible"),
Alex Crichton4b2bdf72017-10-06 21:59:331404 inline_in_all_cgus: Option<bool> = (None, parse_opt_bool, [TRACKED],
Samy Kacimi66815c62019-07-23 19:26:011405 "control whether `#[inline]` functions are in all CGUs"),
Amanieu d'Antrasfdf7ba22017-11-06 21:10:491406 tls_model: Option<String> = (None, parse_opt_string, [TRACKED],
Samy Kacimi66815c62019-07-23 19:26:011407 "choose the TLS model to use (`rustc --print tls-models` for details)"),
Robin Kruppe0d6b52c2017-10-09 00:14:001408 saturating_float_casts: bool = (false, parse_bool, [TRACKED],
Robin Kruppe59524412017-11-09 23:24:051409 "make float->int casts UB-free: numbers outside the integer type's range are clipped to \
1410 the max/min integer respectively, and NaN is mapped to 0"),
Michael Woerister94f30372018-01-08 11:30:521411 human_readable_cgu_names: bool = (false, parse_bool, [TRACKED],
1412 "generate human-readable, predictable names for codegen units"),
Adam C. Foltzer8c09d292018-01-15 21:08:271413 dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED],
1414 "in dep-info output, omit targets for tracking dependencies of the dep-info files \
1415 themselves"),
Mark Mansiebfa6c72018-01-15 03:11:401416 unpretty: Option<String> = (None, parse_unpretty, [UNTRACKED],
Brian Andersonc03077b2019-08-07 21:51:491417 "present the input source, unstable (and less-pretty) variants;
Mark Mansiebfa6c72018-01-15 03:11:401418 valid types are any of the types for `--pretty`, as well as:
Hirokazu Hata260fb312019-01-14 15:09:211419 `expanded`, `expanded,identified`,
1420 `expanded,hygiene` (with internal representations),
Mark Mansiebfa6c72018-01-15 03:11:401421 `everybody_loops` (all function bodies replaced with `loop {}`),
Hirokazu Hata260fb312019-01-14 15:09:211422 `hir` (the HIR), `hir,identified`,
1423 `hir,typed` (HIR with types for each node),
1424 `hir-tree` (dump the raw HIR),
1425 `mir` (the MIR), or `mir-cfg` (graphviz formatted MIR)"),
Alex Crichton0f16eee2018-01-26 05:21:021426 run_dsymutil: Option<bool> = (None, parse_opt_bool, [TRACKED],
ljedrz942a7962018-10-10 13:24:311427 "run `dsymutil` and delete intermediate object files"),
Vadim Petrochenkovcdbd8c22018-02-23 00:18:531428 ui_testing: bool = (false, parse_bool, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311429 "format compiler diagnostics in a way that's better suitable for UI testing"),
Alex Crichton0e0f74b2018-03-09 15:25:541430 embed_bitcode: bool = (false, parse_bool, [TRACKED],
ljedrz942a7962018-10-10 13:24:311431 "embed LLVM bitcode in object files"),
Johannes Löthberg2f0dd4a2018-03-20 15:23:311432 strip_debuginfo_if_disabled: Option<bool> = (None, parse_opt_bool, [TRACKED],
1433 "tell the linker to strip debuginfo when building without debuginfo enabled."),
Michael Woerister4f6d05d2018-03-06 09:33:421434 share_generics: Option<bool> = (None, parse_opt_bool, [TRACKED],
ljedrz942a7962018-10-10 13:24:311435 "make the current crate share its generic instantiations"),
Niko Matsakis3aa10852018-03-22 09:19:251436 chalk: bool = (false, parse_bool, [TRACKED],
ljedrz942a7962018-10-10 13:24:311437 "enable the experimental Chalk-based trait solving engine"),
Nikita Popov54f06682018-05-22 17:23:401438 no_parallel_llvm: bool = (false, parse_bool, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311439 "don't run LLVM in parallel (while keeping codegen-units and ThinLTO)"),
Niko Matsakisd9afd2b2018-07-23 14:30:591440 no_leak_check: bool = (false, parse_bool, [UNTRACKED],
1441 "disables the 'leak check' for subtyping; unsound, but useful for tests"),
John Kåre Alsakerbeb0c742019-01-18 06:40:551442 no_interleave_lints: bool = (false, parse_bool, [UNTRACKED],
1443 "don't interleave execution of lints; allows benchmarking individual lints"),
Pietro Albini71276c62018-07-18 18:34:081444 crate_attr: Vec<String> = (Vec::new(), parse_string_push, [TRACKED],
1445 "inject the given attribute in the crate"),
Michael Woerister64ee32e2019-05-28 14:13:591446 self_profile: SwitchWithOptPath = (SwitchWithOptPath::Disabled,
1447 parse_switch_with_opt_path, [UNTRACKED],
Wesley Wiserfccc8412019-02-11 23:11:431448 "run the self profiler and output the raw event data"),
Michael Woerister08efbac2019-04-12 12:48:411449 self_profile_events: Option<Vec<String>> = (None, parse_opt_comma_list, [UNTRACKED],
1450 "specifies which kinds of events get recorded by the self profiler"),
Jorge Aparicio3c0907c2018-09-13 17:43:151451 emit_stack_sizes: bool = (false, parse_bool, [UNTRACKED],
ljedrz942a7962018-10-10 13:24:311452 "emits a section containing stack size metadata"),
Gabriel Majeri6009da02018-09-26 16:19:551453 plt: Option<bool> = (None, parse_opt_bool, [TRACKED],
1454 "whether to use the PLT when calling into shared libraries;
1455 only has effect for PIC code on systems with ELF binaries
1456 (default: PLT is disabled if full relro is enabled)"),
Peter Jinb91d2112018-12-31 18:58:131457 merge_functions: Option<MergeFunctions> = (None, parse_merge_functions, [TRACKED],
1458 "control the operation of the MergeFunctions LLVM pass, taking
1459 the same values as the target option of the same name"),
Tyler Mandry7c59ce92019-03-13 23:29:241460 allow_features: Option<Vec<String>> = (None, parse_opt_comma_list, [TRACKED],
1461 "only allow the listed language features to be enabled in code (space separated)"),
Eduard-Mihai Burtescu20929632019-01-29 05:24:321462 symbol_mangling_version: SymbolManglingVersion = (SymbolManglingVersion::Legacy,
1463 parse_symbol_mangling_version, [TRACKED],
1464 "which mangling version to use for symbol names"),
Mark Rousskovd749b5e2019-07-24 15:00:091465 binary_dep_depinfo: bool = (false, parse_bool, [TRACKED],
1466 "include artifacts (sysroot, crate dependencies) used during compilation in dep-info"),
Xiang Fan10c66812019-09-27 23:13:531467 insert_sideeffect: bool = (false, parse_bool, [TRACKED],
1468 "fix undefined behavior when a thread doesn't eventually make progress \
1469 (such as entering an empty infinite loop) by inserting llvm.sideeffect"),
Manish Goregaokar7e87ea92014-12-09 09:55:491470}
1471
Mark Rousskovc0fdddc2019-10-25 17:23:181472pub const fn default_lib_output() -> CrateType {
Mark Rousskov2a934422018-07-26 17:13:111473 CrateType::Rlib
Nick Cameron37ca3672014-05-06 11:38:011474}
1475
Nick Cameron37ca3672014-05-06 11:38:011476pub fn default_configuration(sess: &Session) -> ast::CrateConfig {
Niko Matsakis68e5bb32015-02-20 19:08:141477 let end = &sess.target.target.target_endian;
1478 let arch = &sess.target.target.arch;
1479 let wordsz = &sess.target.target.target_pointer_width;
1480 let os = &sess.target.target.target_os;
Alex Crichtonba2380d2015-04-21 22:53:321481 let env = &sess.target.target.target_env;
Sebastian Wickiaf68cdf2015-09-23 23:20:431482 let vendor = &sess.target.target.target_vendor;
whitequark5b0700e2016-08-15 09:46:441483 let min_atomic_width = sess.target.target.min_atomic_width();
Jorge Aparicio61360692016-10-04 04:45:401484 let max_atomic_width = sess.target.target.max_atomic_width();
Jorge Apariciobbf688a2018-06-30 19:56:081485 let atomic_cas = sess.target.target.options.atomic_cas;
Nick Cameron37ca3672014-05-06 11:38:011486
Eduard-Mihai Burtescu93f3f5b2018-08-18 10:55:431487 let mut ret = FxHashSet::default();
ljedrz675f00b2018-10-10 13:30:531488 ret.reserve(6); // the minimum number of insertions
Jeffrey Seyfried4b9b0d32016-11-15 08:54:271489 // Target bindings.
Jeffrey Seyfriede85a0d72016-11-16 10:52:371490 ret.insert((Symbol::intern("target_os"), Some(Symbol::intern(os))));
Jeremy Soller4dcb8672016-12-23 05:29:331491 if let Some(ref fam) = sess.target.target.options.target_family {
1492 ret.insert((Symbol::intern("target_family"), Some(Symbol::intern(fam))));
Jeremy Sollerc59bb492016-12-23 05:20:471493 if fam == "windows" || fam == "unix" {
Jeremy Soller4dcb8672016-12-23 05:29:331494 ret.insert((Symbol::intern(fam), None));
Jeremy Sollerc59bb492016-12-23 05:20:471495 }
1496 }
Jeffrey Seyfriede85a0d72016-11-16 10:52:371497 ret.insert((Symbol::intern("target_arch"), Some(Symbol::intern(arch))));
1498 ret.insert((Symbol::intern("target_endian"), Some(Symbol::intern(end))));
Santiago Pastorino52a47d42018-03-06 05:29:031499 ret.insert((
1500 Symbol::intern("target_pointer_width"),
1501 Some(Symbol::intern(wordsz)),
1502 ));
Jeffrey Seyfriede85a0d72016-11-16 10:52:371503 ret.insert((Symbol::intern("target_env"), Some(Symbol::intern(env))));
Santiago Pastorino52a47d42018-03-06 05:29:031504 ret.insert((
1505 Symbol::intern("target_vendor"),
1506 Some(Symbol::intern(vendor)),
1507 ));
Alex Crichtonb67b5a82015-12-10 20:21:551508 if sess.target.target.options.has_elf_tls {
Nicholas Nethercote26451ef2019-05-22 02:42:231509 ret.insert((sym::target_thread_local, None));
Alex Crichtonb67b5a82015-12-10 20:21:551510 }
Amanieu d'Antras04835ea2016-04-15 19:16:191511 for &i in &[8, 16, 32, 64, 128] {
whitequark5b0700e2016-08-15 09:46:441512 if i >= min_atomic_width && i <= max_atomic_width {
Amanieu d'Antrasdfe76a12019-10-08 16:09:231513 let mut insert_atomic = |s| {
Santiago Pastorino52a47d42018-03-06 05:29:031514 ret.insert((
Amanieu d'Antrasdfe76a12019-10-08 16:09:231515 sym::target_has_atomic_load_store,
1516 Some(Symbol::intern(s)),
Santiago Pastorino52a47d42018-03-06 05:29:031517 ));
Amanieu d'Antrasdfe76a12019-10-08 16:09:231518 if atomic_cas {
1519 ret.insert((
1520 sym::target_has_atomic,
1521 Some(Symbol::intern(s))
1522 ));
1523 }
1524 };
1525 let s = i.to_string();
1526 insert_atomic(&s);
1527 if &s == wordsz {
1528 insert_atomic("ptr");
Amanieu d'Antras04835ea2016-04-15 19:16:191529 }
1530 }
1531 }
Alex Crichtond5d83452015-03-02 22:51:241532 if sess.opts.debug_assertions {
Jeffrey Seyfriedd2f8fb02016-11-16 08:21:521533 ret.insert((Symbol::intern("debug_assertions"), None));
Alex Crichtond5d83452015-03-02 22:51:241534 }
Mark Rousskov2a934422018-07-26 17:13:111535 if sess.opts.crate_types.contains(&CrateType::ProcMacro) {
Nicholas Nethercote26451ef2019-05-22 02:42:231536 ret.insert((sym::proc_macro, None));
Alex Crichtonecc6c392016-08-23 00:07:111537 }
ljedrz0b2e9f72018-10-10 13:33:101538 ret
Nick Cameron37ca3672014-05-06 11:38:011539}
1540
Alexander Regueiroc1d29ee2019-09-06 02:57:441541/// Converts the crate `cfg!` configuration from `String` to `Symbol`.
John Kåre Alsaker51938c62018-12-08 19:30:231542/// `rustc_interface::interface::Config` accepts this in the compiler configuration,
1543/// but the symbol interner is not yet set up then, so we must convert it later.
1544pub fn to_crate_config(cfg: FxHashSet<(String, Option<String>)>) -> ast::CrateConfig {
1545 cfg.into_iter()
1546 .map(|(a, b)| (Symbol::intern(&a), b.map(|b| Symbol::intern(&b))))
1547 .collect()
1548}
1549
Santiago Pastorino52a47d42018-03-06 05:29:031550pub fn build_configuration(sess: &Session, mut user_cfg: ast::CrateConfig) -> ast::CrateConfig {
Nick Cameron37ca3672014-05-06 11:38:011551 // Combine the configuration requested by the session (command line) with
Alexander Regueiroc1d29ee2019-09-06 02:57:441552 // some default and generated configuration items.
Nick Cameron37ca3672014-05-06 11:38:011553 let default_cfg = default_configuration(sess);
Alexander Regueiroc1d29ee2019-09-06 02:57:441554 // If the user wants a test runner, then add the test cfg.
Nick Cameron37ca3672014-05-06 11:38:011555 if sess.opts.test {
Nicholas Nethercote26451ef2019-05-22 02:42:231556 user_cfg.insert((sym::test, None));
Nick Cameron37ca3672014-05-06 11:38:011557 }
Jeffrey Seyfried4b9b0d32016-11-15 08:54:271558 user_cfg.extend(default_cfg.iter().cloned());
1559 user_cfg
Nick Cameron37ca3672014-05-06 11:38:011560}
1561
Nick Cameron6309b0f2015-12-13 22:17:551562pub fn build_target_config(opts: &Options, sp: &Handler) -> Config {
ljedrz0b2e9f72018-10-10 13:33:101563 let target = Target::search(&opts.target_triple).unwrap_or_else(|e| {
1564 sp.struct_fatal(&format!("Error loading target specification: {}", e))
1565 .help("Use `--print target-list` for a list of built-in targets")
1566 .emit();
1567 FatalError.raise();
1568 });
Corey Richardson6b130e32014-07-23 18:56:361569
Eduard-Mihai Burtescu3ce31eb2017-08-05 09:27:281570 let (isize_ty, usize_ty) = match &target.target_pointer_width[..] {
Jake Gouldingbc7595c2016-05-06 13:31:111571 "16" => (ast::IntTy::I16, ast::UintTy::U16),
Oliver Schneider625e78b2016-02-08 15:20:571572 "32" => (ast::IntTy::I32, ast::UintTy::U32),
1573 "64" => (ast::IntTy::I64, ast::UintTy::U64),
Santiago Pastorino52a47d42018-03-06 05:29:031574 w => sp.fatal(&format!(
1575 "target specification was invalid: \
1576 unrecognized target-pointer-width {}",
1577 w
1578 )).raise(),
Nick Cameron37ca3672014-05-06 11:38:011579 };
Corey Richardson6b130e32014-07-23 18:56:361580
Nick Cameron37ca3672014-05-06 11:38:011581 Config {
Zack M. Davisf6689992017-07-03 18:19:511582 target,
Eduard-Mihai Burtescu3ce31eb2017-08-05 09:27:281583 isize_ty,
1584 usize_ty,
Nick Cameron37ca3672014-05-06 11:38:011585 }
1586}
1587
Jorge Aparicio788181d2015-01-28 13:34:181588#[derive(Copy, Clone, PartialEq, Eq, Debug)]
Alex Crichton12828332016-02-20 06:03:541589pub enum OptionStability {
1590 Stable,
Alex Crichton12828332016-02-20 06:03:541591 Unstable,
1592}
Felix S. Klock IIe711e2d2014-12-17 13:42:501593
Felix S. Klock IIe711e2d2014-12-17 13:42:501594pub struct RustcOptGroup {
Manish Goregaokar69c53ac2018-02-23 17:53:001595 pub apply: Box<dyn Fn(&mut getopts::Options) -> &mut getopts::Options>,
Alex Crichton5c3d0e62017-06-08 21:20:551596 pub name: &'static str,
Felix S. Klock IIe711e2d2014-12-17 13:42:501597 pub stability: OptionStability,
1598}
1599
1600impl RustcOptGroup {
1601 pub fn is_stable(&self) -> bool {
1602 self.stability == OptionStability::Stable
1603 }
1604
Alex Crichton5c3d0e62017-06-08 21:20:551605 pub fn stable<F>(name: &'static str, f: F) -> RustcOptGroup
Santiago Pastorino52a47d42018-03-06 05:29:031606 where
1607 F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static,
Alex Crichton5c3d0e62017-06-08 21:20:551608 {
1609 RustcOptGroup {
Zack M. Davisf6689992017-07-03 18:19:511610 name,
Alex Crichton5c3d0e62017-06-08 21:20:551611 apply: Box::new(f),
1612 stability: OptionStability::Stable,
1613 }
Felix S. Klock IIe711e2d2014-12-17 13:42:501614 }
1615
Alex Crichton5c3d0e62017-06-08 21:20:551616 pub fn unstable<F>(name: &'static str, f: F) -> RustcOptGroup
Santiago Pastorino52a47d42018-03-06 05:29:031617 where
1618 F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static,
Alex Crichton5c3d0e62017-06-08 21:20:551619 {
1620 RustcOptGroup {
Zack M. Davisf6689992017-07-03 18:19:511621 name,
Alex Crichton5c3d0e62017-06-08 21:20:551622 apply: Box::new(f),
1623 stability: OptionStability::Unstable,
1624 }
Felix S. Klock IIe711e2d2014-12-17 13:42:501625 }
1626}
1627
1628// The `opt` local module holds wrappers around the `getopts` API that
1629// adds extra rustc-specific metadata to each option; such metadata
1630// is exposed by . The public
1631// functions below ending with `_u` are the functions that return
Alexander Regueiroee89c082018-11-27 02:59:491632// *unstable* options, i.e., options that are only enabled when the
Felix S. Klock IIe711e2d2014-12-17 13:42:501633// user also passes the `-Z unstable-options` debugging flag.
1634mod opt {
Vadim Petrochenkov43415212019-07-23 17:34:171635 // The `fn flag*` etc below are written so that we can use them
Felix S. Klock IIe711e2d2014-12-17 13:42:501636 // in the future; do not warn about them not being used right now.
1637 #![allow(dead_code)]
1638
1639 use getopts;
1640 use super::RustcOptGroup;
1641
Nick Cameron46aa6212015-03-11 21:44:561642 pub type R = RustcOptGroup;
Alex Crichton5c3d0e62017-06-08 21:20:551643 pub type S = &'static str;
Felix S. Klock IIe711e2d2014-12-17 13:42:501644
Alex Crichton5c3d0e62017-06-08 21:20:551645 fn stable<F>(name: S, f: F) -> R
Santiago Pastorino52a47d42018-03-06 05:29:031646 where
1647 F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static,
Alex Crichton5c3d0e62017-06-08 21:20:551648 {
1649 RustcOptGroup::stable(name, f)
1650 }
1651
1652 fn unstable<F>(name: S, f: F) -> R
Santiago Pastorino52a47d42018-03-06 05:29:031653 where
1654 F: Fn(&mut getopts::Options) -> &mut getopts::Options + 'static,
Alex Crichton5c3d0e62017-06-08 21:20:551655 {
1656 RustcOptGroup::unstable(name, f)
1657 }
1658
1659 fn longer(a: S, b: S) -> S {
1660 if a.len() > b.len() {
1661 a
1662 } else {
1663 b
1664 }
1665 }
Felix S. Klock IIe711e2d2014-12-17 13:42:501666
Alex Crichton12828332016-02-20 06:03:541667 pub fn opt_s(a: S, b: S, c: S, d: S) -> R {
Alex Crichton5c3d0e62017-06-08 21:20:551668 stable(longer(a, b), move |opts| opts.optopt(a, b, c, d))
Alex Crichton12828332016-02-20 06:03:541669 }
1670 pub fn multi_s(a: S, b: S, c: S, d: S) -> R {
Alex Crichton5c3d0e62017-06-08 21:20:551671 stable(longer(a, b), move |opts| opts.optmulti(a, b, c, d))
Alex Crichton12828332016-02-20 06:03:541672 }
1673 pub fn flag_s(a: S, b: S, c: S) -> R {
Alex Crichton5c3d0e62017-06-08 21:20:551674 stable(longer(a, b), move |opts| opts.optflag(a, b, c))
Alex Crichton12828332016-02-20 06:03:541675 }
1676 pub fn flagopt_s(a: S, b: S, c: S, d: S) -> R {
Alex Crichton5c3d0e62017-06-08 21:20:551677 stable(longer(a, b), move |opts| opts.optflagopt(a, b, c, d))
Alex Crichton12828332016-02-20 06:03:541678 }
1679 pub fn flagmulti_s(a: S, b: S, c: S) -> R {
Alex Crichton5c3d0e62017-06-08 21:20:551680 stable(longer(a, b), move |opts| opts.optflagmulti(a, b, c))
Alex Crichton12828332016-02-20 06:03:541681 }
Felix S. Klock IIe711e2d2014-12-17 13:42:501682
Alex Crichton12828332016-02-20 06:03:541683 pub fn opt(a: S, b: S, c: S, d: S) -> R {
Alex Crichton5c3d0e62017-06-08 21:20:551684 unstable(longer(a, b), move |opts| opts.optopt(a, b, c, d))
Alex Crichton12828332016-02-20 06:03:541685 }
1686 pub fn multi(a: S, b: S, c: S, d: S) -> R {
Alex Crichton5c3d0e62017-06-08 21:20:551687 unstable(longer(a, b), move |opts| opts.optmulti(a, b, c, d))
Alex Crichton12828332016-02-20 06:03:541688 }
1689 pub fn flag(a: S, b: S, c: S) -> R {
Alex Crichton5c3d0e62017-06-08 21:20:551690 unstable(longer(a, b), move |opts| opts.optflag(a, b, c))
Alex Crichton12828332016-02-20 06:03:541691 }
1692 pub fn flagopt(a: S, b: S, c: S, d: S) -> R {
Alex Crichton5c3d0e62017-06-08 21:20:551693 unstable(longer(a, b), move |opts| opts.optflagopt(a, b, c, d))
Alex Crichton12828332016-02-20 06:03:541694 }
1695 pub fn flagmulti(a: S, b: S, c: S) -> R {
Alex Crichton5c3d0e62017-06-08 21:20:551696 unstable(longer(a, b), move |opts| opts.optflagmulti(a, b, c))
Alex Crichton12828332016-02-20 06:03:541697 }
Felix S. Klock IIe711e2d2014-12-17 13:42:501698}
1699
1700/// Returns the "short" subset of the rustc command line options,
1701/// including metadata for each option, such as whether the option is
1702/// part of the stable long-term interface for rustc.
1703pub fn rustc_short_optgroups() -> Vec<RustcOptGroup> {
Alex Crichton117984b2014-12-16 00:03:391704 vec![
Alex Crichton12828332016-02-20 06:03:541705 opt::flag_s("h", "help", "Display this message"),
1706 opt::multi_s("", "cfg", "Configure the compilation environment", "SPEC"),
Santiago Pastorino52a47d42018-03-06 05:29:031707 opt::multi_s(
1708 "L",
1709 "",
1710 "Add a directory to the library search path. The
pravic9da67da2016-04-15 20:55:421711 optional KIND can be one of dependency, crate, native,
Tshepang Lekhonkhobe83530072019-07-06 03:30:151712 framework, or all (the default).",
Santiago Pastorino52a47d42018-03-06 05:29:031713 "[KIND=]PATH",
1714 ),
1715 opt::multi_s(
1716 "l",
1717 "",
1718 "Link the generated crate(s) to the specified native
Matt Kraai43a0f412016-04-10 13:59:191719 library NAME. The optional KIND can be one of
Tshepang Lekhonkhobe83530072019-07-06 03:30:151720 static, framework, or dylib (the default).",
Santiago Pastorino52a47d42018-03-06 05:29:031721 "[KIND=]NAME",
1722 ),
Aaron Hill14986082019-07-20 20:34:411723 make_crate_type_option(),
Santiago Pastorino52a47d42018-03-06 05:29:031724 opt::opt_s(
1725 "",
1726 "crate-name",
1727 "Specify the name of the crate being built",
1728 "NAME",
1729 ),
Peter Hall3eb4eae2019-03-22 11:51:371730 opt::opt_s(
1731 "",
1732 "edition",
1733 "Specify which edition of the compiler to use when compiling code.",
1734 EDITION_NAME_LIST,
1735 ),
Santiago Pastorino52a47d42018-03-06 05:29:031736 opt::multi_s(
1737 "",
1738 "emit",
1739 "Comma separated list of types of output for \
1740 the compiler to emit",
1741 "[asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]",
1742 ),
1743 opt::multi_s(
1744 "",
1745 "print",
Eric Husse392db62019-05-12 21:16:501746 "Compiler information to print on stdout",
Santiago Pastorino52a47d42018-03-06 05:29:031747 "[crate-name|file-names|sysroot|cfg|target-list|\
1748 target-cpus|target-features|relocation-models|\
1749 code-models|tls-models|target-spec-json|native-static-libs]",
1750 ),
1751 opt::flagmulti_s("g", "", "Equivalent to -C debuginfo=2"),
Alex Crichton12828332016-02-20 06:03:541752 opt::flagmulti_s("O", "", "Equivalent to -C opt-level=2"),
1753 opt::opt_s("o", "", "Write output to <filename>", "FILENAME"),
Santiago Pastorino52a47d42018-03-06 05:29:031754 opt::opt_s(
1755 "",
1756 "out-dir",
1757 "Write output to compiler-chosen filename \
1758 in <dir>",
1759 "DIR",
1760 ),
1761 opt::opt_s(
1762 "",
1763 "explain",
1764 "Provide a detailed explanation of an error \
1765 message",
1766 "OPT",
1767 ),
Alex Crichton12828332016-02-20 06:03:541768 opt::flag_s("", "test", "Build a test harness"),
Santiago Pastorino52a47d42018-03-06 05:29:031769 opt::opt_s(
1770 "",
1771 "target",
1772 "Target triple for which the code is compiled",
1773 "TARGET",
1774 ),
Alex Crichton12828332016-02-20 06:03:541775 opt::multi_s("W", "warn", "Set lint warnings", "OPT"),
1776 opt::multi_s("A", "allow", "Set lint allowed", "OPT"),
1777 opt::multi_s("D", "deny", "Set lint denied", "OPT"),
1778 opt::multi_s("F", "forbid", "Set lint forbidden", "OPT"),
Santiago Pastorino52a47d42018-03-06 05:29:031779 opt::multi_s(
1780 "",
1781 "cap-lints",
1782 "Set the most restrictive lint level. \
1783 More restrictive lints are capped at this \
1784 level",
1785 "LEVEL",
1786 ),
Alex Crichton12828332016-02-20 06:03:541787 opt::multi_s("C", "codegen", "Set a codegen option", "OPT[=VALUE]"),
1788 opt::flag_s("V", "version", "Print version info and exit"),
1789 opt::flag_s("v", "verbose", "Use verbose output"),
Alex Crichton117984b2014-12-16 00:03:391790 ]
1791}
1792
Felix S. Klock IIe711e2d2014-12-17 13:42:501793/// Returns all rustc command line options, including metadata for
1794/// each option, such as whether the option is part of the stable
1795/// long-term interface for rustc.
1796pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
1797 let mut opts = rustc_short_optgroups();
Alex Crichton5c3d0e62017-06-08 21:20:551798 opts.extend(vec![
Santiago Pastorino52a47d42018-03-06 05:29:031799 opt::multi_s(
1800 "",
1801 "extern",
1802 "Specify where an external rust library is located",
1803 "NAME=PATH",
1804 ),
Aaron Hill48ec29d2019-01-30 20:33:501805 opt::multi_s(
1806 "",
1807 "extern-private",
1808 "Specify where an extern rust library is located, marking it as a private dependency",
1809 "NAME=PATH",
1810 ),
Alex Crichton12828332016-02-20 06:03:541811 opt::opt_s("", "sysroot", "Override the system root", "PATH"),
Alex Crichtonccbcc722017-05-04 16:34:441812 opt::multi("Z", "", "Set internal debugging options", "FLAG"),
Santiago Pastorino52a47d42018-03-06 05:29:031813 opt::opt_s(
1814 "",
1815 "error-format",
1816 "How errors and other messages are produced",
1817 "human|json|short",
1818 ),
Alex Crichton17312332019-07-17 19:52:561819 opt::multi_s(
Oliver Scherer96404ee2019-03-12 12:06:431820 "",
Alex Crichton17312332019-07-17 19:52:561821 "json",
1822 "Configure the JSON output of the compiler",
1823 "CONFIG",
Oliver Scherer96404ee2019-03-12 12:06:431824 ),
Santiago Pastorino52a47d42018-03-06 05:29:031825 opt::opt_s(
1826 "",
1827 "color",
1828 "Configure coloring of output:
Guillaume Gomezded701b2016-03-15 08:09:291829 auto = colorize, if output goes to a tty (default);
1830 always = always colorize output;
Santiago Pastorino52a47d42018-03-06 05:29:031831 never = never colorize output",
1832 "auto|always|never",
1833 ),
1834 opt::opt(
1835 "",
1836 "pretty",
1837 "Pretty-print the input instead of compiling;
Alex Crichton7694ca42017-09-23 04:34:271838 valid types are: `normal` (un-annotated source),
1839 `expanded` (crates expanded), or
1840 `expanded,identified` (fully parenthesized, AST nodes with IDs).",
Santiago Pastorino52a47d42018-03-06 05:29:031841 "TYPE",
1842 ),
1843 opt::multi_s(
1844 "",
1845 "remap-path-prefix",
Jeremy Fitzhardinge6d534d52018-03-13 20:26:071846 "Remap source names in all output (compiler messages and output files)",
Santiago Pastorino52a47d42018-03-06 05:29:031847 "FROM=TO",
1848 ),
Alex Crichton117984b2014-12-16 00:03:391849 ]);
1850 opts
Nick Cameron37ca3672014-05-06 11:38:011851}
1852
Guillaume Gomeze221be82018-06-23 13:09:211853pub fn get_cmd_lint_options(matches: &getopts::Matches,
1854 error_format: ErrorOutputType)
1855 -> (Vec<(String, lint::Level)>, bool, Option<lint::Level>) {
1856 let mut lint_opts = vec![];
1857 let mut describe_lints = false;
1858
1859 for &level in &[lint::Allow, lint::Warn, lint::Deny, lint::Forbid] {
1860 for lint_name in matches.opt_strs(level.as_str()) {
1861 if lint_name == "help" {
1862 describe_lints = true;
1863 } else {
1864 lint_opts.push((lint_name.replace("-", "_"), level));
1865 }
1866 }
1867 }
1868
1869 let lint_cap = matches.opt_str("cap-lints").map(|cap| {
1870 lint::Level::from_str(&cap)
1871 .unwrap_or_else(|| early_error(error_format, &format!("unknown lint level: `{}`", cap)))
1872 });
1873 (lint_opts, describe_lints, lint_cap)
1874}
1875
Alexander Regueiroc1d29ee2019-09-06 02:57:441876/// Parses the `--color` flag.
Alex Crichton17312332019-07-17 19:52:561877pub fn parse_color(matches: &getopts::Matches) -> ColorConfig {
1878 match matches.opt_str("color").as_ref().map(|s| &s[..]) {
Santiago Pastorino52a47d42018-03-06 05:29:031879 Some("auto") => ColorConfig::Auto,
Nick Cameron6309b0f2015-12-13 22:17:551880 Some("always") => ColorConfig::Always,
Santiago Pastorino52a47d42018-03-06 05:29:031881 Some("never") => ColorConfig::Never,
Barosl Lee71f39c1a2015-08-22 14:51:531882
Nick Cameron6309b0f2015-12-13 22:17:551883 None => ColorConfig::Auto,
Barosl Lee71f39c1a2015-08-22 14:51:531884
Santiago Pastorino52a47d42018-03-06 05:29:031885 Some(arg) => early_error(
1886 ErrorOutputType::default(),
1887 &format!(
Alexander Regueiroc1d29ee2019-09-06 02:57:441888 "argument for `--color` must be auto, \
Santiago Pastorino52a47d42018-03-06 05:29:031889 always or never (instead was `{}`)",
1890 arg
1891 ),
1892 ),
Alex Crichton17312332019-07-17 19:52:561893 }
1894}
Barosl Lee71f39c1a2015-08-22 14:51:531895
Alex Crichton17312332019-07-17 19:52:561896/// Parse the `--json` flag.
1897///
1898/// The first value returned is how to render JSON diagnostics, and the second
1899/// is whether or not artifact notifications are enabled.
1900pub fn parse_json(matches: &getopts::Matches) -> (HumanReadableErrorType, bool) {
1901 let mut json_rendered: fn(ColorConfig) -> HumanReadableErrorType =
1902 HumanReadableErrorType::Default;
1903 let mut json_color = ColorConfig::Never;
1904 let mut json_artifact_notifications = false;
1905 for option in matches.opt_strs("json") {
1906 // For now conservatively forbid `--color` with `--json` since `--json`
1907 // won't actually be emitting any colors and anything colorized is
1908 // embedded in a diagnostic message anyway.
1909 if matches.opt_str("color").is_some() {
ljedrz0b2e9f72018-10-10 13:33:101910 early_error(
Kurtis Nusbaum51f51102018-04-19 20:56:261911 ErrorOutputType::default(),
Alex Crichton17312332019-07-17 19:52:561912 "cannot specify the `--color` option with `--json`",
1913 );
1914 }
Kurtis Nusbaum51f51102018-04-19 20:56:261915
Alex Crichton17312332019-07-17 19:52:561916 for sub_option in option.split(',') {
1917 match sub_option {
1918 "diagnostic-short" => json_rendered = HumanReadableErrorType::Short,
1919 "diagnostic-rendered-ansi" => json_color = ColorConfig::Always,
1920 "artifacts" => json_artifact_notifications = true,
1921 s => {
1922 early_error(
1923 ErrorOutputType::default(),
1924 &format!("unknown `--json` option `{}`", s),
1925 )
1926 }
1927 }
1928 }
Kurtis Nusbaum320fdaa2018-04-20 04:03:211929 }
Alex Crichton17312332019-07-17 19:52:561930 (json_rendered(json_color), json_artifact_notifications)
1931}
Kurtis Nusbaum320fdaa2018-04-20 04:03:211932
Alexander Regueiroc1d29ee2019-09-06 02:57:441933/// Parses the `--error-format` flag.
Alex Crichton17312332019-07-17 19:52:561934pub fn parse_error_format(
1935 matches: &getopts::Matches,
1936 color: ColorConfig,
1937 json_rendered: HumanReadableErrorType,
1938) -> ErrorOutputType {
Alexander Regueiroc1d29ee2019-09-06 02:57:441939 // We need the `opts_present` check because the driver will send us Matches
Nick Cameron82f8e5c2016-01-06 20:23:011940 // with only stable options if no unstable options are used. Since error-format
Alexander Regueiroc1d29ee2019-09-06 02:57:441941 // is unstable, it will not be present. We have to use `opts_present` not
1942 // `opt_present` because the latter will panic.
Nick Cameron82f8e5c2016-01-06 20:23:011943 let error_format = if matches.opts_present(&["error-format".to_owned()]) {
1944 match matches.opt_str("error-format").as_ref().map(|s| &s[..]) {
Oliver Scherer39b21372019-03-25 10:16:581945 None |
1946 Some("human") => ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color)),
Philipp Hanschc04a2cc2019-05-31 19:15:591947 Some("human-annotate-rs") => {
Philipp Hanschdf076b22019-06-05 19:13:561948 ErrorOutputType::HumanReadable(HumanReadableErrorType::AnnotateSnippet(color))
Philipp Hanschc04a2cc2019-05-31 19:15:591949 },
Oliver Scherer39b21372019-03-25 10:16:581950 Some("json") => ErrorOutputType::Json { pretty: false, json_rendered },
1951 Some("pretty-json") => ErrorOutputType::Json { pretty: true, json_rendered },
1952 Some("short") => ErrorOutputType::HumanReadable(HumanReadableErrorType::Short(color)),
Nick Cameronfd46c782015-12-31 03:50:061953
Santiago Pastorino52a47d42018-03-06 05:29:031954 Some(arg) => early_error(
Oliver Scherer39b21372019-03-25 10:16:581955 ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color)),
Santiago Pastorino52a47d42018-03-06 05:29:031956 &format!(
Alexander Regueiro022d9c82019-09-01 17:09:591957 "argument for `--error-format` must be `human`, `json` or \
Santiago Pastorino52a47d42018-03-06 05:29:031958 `short` (instead was `{}`)",
1959 arg
1960 ),
1961 ),
Nick Cameronfd46c782015-12-31 03:50:061962 }
1963 } else {
Oliver Scherer39b21372019-03-25 10:16:581964 ErrorOutputType::HumanReadable(HumanReadableErrorType::Default(color))
Nick Cameronfd46c782015-12-31 03:50:061965 };
1966
Alex Crichton17312332019-07-17 19:52:561967 match error_format {
1968 ErrorOutputType::Json { .. } => {}
1969
1970 // Conservatively require that the `--json` argument is coupled with
1971 // `--error-format=json`. This means that `--json` is specified we
1972 // should actually be emitting JSON blobs.
1973 _ if matches.opt_strs("json").len() > 0 => {
1974 early_error(
1975 ErrorOutputType::default(),
1976 "using `--json` requires also using `--error-format=json`",
1977 );
1978 }
1979
1980 _ => {}
1981 }
1982
1983 return error_format;
1984}
1985
Mazdak Farrokhzad9d766ed2019-10-11 21:30:581986fn parse_crate_edition(matches: &getopts::Matches) -> Edition {
Alex Crichton17312332019-07-17 19:52:561987 let edition = match matches.opt_str("edition") {
1988 Some(arg) => Edition::from_str(&arg).unwrap_or_else(|_|
1989 early_error(
1990 ErrorOutputType::default(),
1991 &format!(
Alexander Regueiro022d9c82019-09-01 17:09:591992 "argument for `--edition` must be one of: \
Alex Crichton17312332019-07-17 19:52:561993 {}. (instead was `{}`)",
1994 EDITION_NAME_LIST,
1995 arg
1996 ),
1997 ),
1998 ),
1999 None => DEFAULT_EDITION,
2000 };
2001
2002 if !edition.is_stable() && !nightly_options::is_nightly_build() {
2003 early_error(
2004 ErrorOutputType::default(),
2005 &format!(
Alexander Regueiro022d9c82019-09-01 17:09:592006 "edition {} is unstable and only \
Alex Crichton17312332019-07-17 19:52:562007 available for nightly builds of rustc.",
2008 edition,
2009 )
2010 )
2011 }
2012
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582013 edition
2014}
Alex Crichton17312332019-07-17 19:52:562015
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582016fn check_debug_option_stability(
2017 debugging_opts: &DebuggingOptions,
2018 error_format: ErrorOutputType,
2019 json_rendered: HumanReadableErrorType,
2020) {
Oliver Scherer96404ee2019-03-12 12:06:432021 if !debugging_opts.unstable_options {
Oliver Scherer39b21372019-03-25 10:16:582022 if let ErrorOutputType::Json { pretty: true, json_rendered } = error_format {
Oliver Scherer96404ee2019-03-12 12:06:432023 early_error(
Oliver Scherer39b21372019-03-25 10:16:582024 ErrorOutputType::Json { pretty: false, json_rendered },
Alexander Regueiro022d9c82019-09-01 17:09:592025 "`--error-format=pretty-json` is unstable",
Oliver Scherer96404ee2019-03-12 12:06:432026 );
2027 }
Philipp Hanschdf076b22019-06-05 19:13:562028 if let ErrorOutputType::HumanReadable(HumanReadableErrorType::AnnotateSnippet(_)) =
Philipp Hanschc04a2cc2019-05-31 19:15:592029 error_format {
2030 early_error(
2031 ErrorOutputType::Json { pretty: false, json_rendered },
Alexander Regueiro022d9c82019-09-01 17:09:592032 "`--error-format=human-annotate-rs` is unstable",
Philipp Hanschc04a2cc2019-05-31 19:15:592033 );
2034 }
Oliver Schneiderc7cb2cf2017-11-03 12:38:262035 }
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582036}
Oliver Schneiderc7cb2cf2017-11-03 12:38:262037
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582038fn parse_output_types(
2039 debugging_opts: &DebuggingOptions,
2040 matches: &getopts::Matches,
2041 error_format: ErrorOutputType,
2042) -> OutputTypes {
Michael Woerister32414312016-08-02 20:53:582043 let mut output_types = BTreeMap::new();
Eduard Burtescua6199012016-05-25 05:46:362044 if !debugging_opts.parse_only {
Alex Crichton8c963c02015-09-30 17:08:372045 for list in matches.opt_strs("emit") {
2046 for output_type in list.split(',') {
2047 let mut parts = output_type.splitn(2, '=');
Corey Farwellc3ea3582017-11-05 14:20:592048 let shorthand = parts.next().unwrap();
ljedrz0b2e9f72018-10-10 13:33:102049 let output_type = OutputType::from_shorthand(shorthand).unwrap_or_else(||
2050 early_error(
Santiago Pastorino52a47d42018-03-06 05:29:032051 error_format,
2052 &format!(
2053 "unknown emission type: `{}` - expected one of: {}",
2054 shorthand,
2055 OutputType::shorthands_display(),
2056 ),
2057 ),
ljedrz0b2e9f72018-10-10 13:33:102058 );
Alex Crichton8c963c02015-09-30 17:08:372059 let path = parts.next().map(PathBuf::from);
2060 output_types.insert(output_type, path);
Nick Cameron37ca3672014-05-06 11:38:012061 }
2062 }
2063 };
Michael Kohl9873acc2017-05-28 06:49:142064 if output_types.is_empty() {
Alex Crichton8c963c02015-09-30 17:08:372065 output_types.insert(OutputType::Exe, None);
Nick Cameron37ca3672014-05-06 11:38:012066 }
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582067 OutputTypes(output_types)
2068}
Nick Cameron37ca3672014-05-06 11:38:012069
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582070fn should_override_cgus_and_disable_thinlto(
2071 output_types: &OutputTypes,
2072 matches: &getopts::Matches,
2073 error_format: ErrorOutputType,
2074 mut codegen_units: Option<usize>,
2075) -> (bool, Option<usize>) {
Alex Crichton8bde2ac2018-01-16 23:02:312076 let mut disable_thinlto = false;
Alexander Regueiroc1d29ee2019-09-06 02:57:442077 // Issue #30063: if user requests LLVM-related output to one
Felix S. Klock IIf90c21a2015-12-04 18:35:162078 // particular path, disable codegen-units.
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582079 let incompatible: Vec<_> = output_types.0
Santiago Pastorino52a47d42018-03-06 05:29:032080 .iter()
Alex Crichton9e35b792017-09-25 19:26:252081 .map(|ot_path| ot_path.0)
Santiago Pastorino52a47d42018-03-06 05:29:032082 .filter(|ot| !ot.is_compatible_with_codegen_units_and_single_output_file())
Alex Crichton9e35b792017-09-25 19:26:252083 .map(|ot| ot.shorthand())
2084 .collect();
2085 if !incompatible.is_empty() {
2086 match codegen_units {
2087 Some(n) if n > 1 => {
2088 if matches.opt_present("o") {
2089 for ot in &incompatible {
Santiago Pastorino52a47d42018-03-06 05:29:032090 early_warn(
2091 error_format,
2092 &format!(
Alexander Regueiro022d9c82019-09-01 17:09:592093 "`--emit={}` with `-o` incompatible with \
2094 `-C codegen-units=N` for N > 1",
Santiago Pastorino52a47d42018-03-06 05:29:032095 ot
2096 ),
2097 );
Alex Crichton9e35b792017-09-25 19:26:252098 }
2099 early_warn(error_format, "resetting to default -C codegen-units=1");
2100 codegen_units = Some(1);
Alex Crichton8bde2ac2018-01-16 23:02:312101 disable_thinlto = true;
Alex Crichton9e35b792017-09-25 19:26:252102 }
Felix S. Klock IIf90c21a2015-12-04 18:35:162103 }
Alex Crichton855f6d12017-11-25 19:13:582104 _ => {
2105 codegen_units = Some(1);
Alex Crichton8bde2ac2018-01-16 23:02:312106 disable_thinlto = true;
Alex Crichton855f6d12017-11-25 19:13:582107 }
Felix S. Klock IIf90c21a2015-12-04 18:35:162108 }
2109 }
2110
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582111 if codegen_units == Some(0) {
2112 early_error(
2113 error_format,
2114 "value for codegen units must be a positive non-zero integer",
2115 );
2116 }
2117
2118 (disable_thinlto, codegen_units)
2119}
2120
2121fn check_thread_count(debugging_opts: &DebuggingOptions, error_format: ErrorOutputType) {
Mark Rousskov1a1067d2019-09-30 20:27:282122 if debugging_opts.threads == 0 {
Santiago Pastorino52a47d42018-03-06 05:29:032123 early_error(
2124 error_format,
Alexander Regueiro022d9c82019-09-01 17:09:592125 "value for threads must be a positive non-zero integer",
Santiago Pastorino52a47d42018-03-06 05:29:032126 );
John Kåre Alsakeraa6065b2017-12-03 13:16:192127 }
2128
Mark Rousskov1a1067d2019-09-30 20:27:282129 if debugging_opts.threads > 1 && debugging_opts.fuel.is_some() {
John Kåre Alsakera46f0592018-04-01 06:20:392130 early_error(
2131 error_format,
Alexander Regueiro022d9c82019-09-01 17:09:592132 "optimization fuel is incompatible with multiple threads",
John Kåre Alsakera46f0592018-04-01 06:20:392133 );
2134 }
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582135}
John Kåre Alsakera46f0592018-04-01 06:20:392136
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582137fn select_incremental_path(
2138 debugging_opts: &DebuggingOptions,
2139 cg: &CodegenOptions,
2140 error_format: ErrorOutputType,
2141) -> Option<PathBuf> {
2142 match (&debugging_opts.incremental, &cg.incremental) {
2143 (Some(path1), Some(path2)) => {
Michael Woerister796264b2017-12-15 20:03:482144 if path1 != path2 {
Santiago Pastorino52a47d42018-03-06 05:29:032145 early_error(
2146 error_format,
2147 &format!(
2148 "conflicting paths for `-Z incremental` and \
2149 `-C incremental` specified: {} versus {}",
2150 path1, path2
2151 ),
2152 );
Michael Woerister796264b2017-12-15 20:03:482153 } else {
2154 Some(path1)
2155 }
2156 }
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582157 (Some(path), None) => Some(path),
2158 (None, Some(path)) => Some(path),
2159 (None, None) => None,
2160 }.map(|m| PathBuf::from(m))
2161}
Michael Woerister796264b2017-12-15 20:03:482162
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582163fn collect_print_requests(
2164 cg: &mut CodegenOptions,
2165 dopts: &mut DebuggingOptions,
2166 matches: &getopts::Matches,
2167 is_unstable_enabled: bool,
2168 error_format: ErrorOutputType,
2169) -> Vec<PrintRequest> {
Cameron Harte1efa322016-07-10 14:22:132170 let mut prints = Vec::<PrintRequest>::new();
2171 if cg.target_cpu.as_ref().map_or(false, |s| s == "help") {
2172 prints.push(PrintRequest::TargetCPUs);
2173 cg.target_cpu = None;
2174 };
2175 if cg.target_feature == "help" {
2176 prints.push(PrintRequest::TargetFeatures);
Matthias Krügerede1f7d2018-08-23 08:14:522177 cg.target_feature = String::new();
Cameron Harte1efa322016-07-10 14:22:132178 }
2179 if cg.relocation_model.as_ref().map_or(false, |s| s == "help") {
2180 prints.push(PrintRequest::RelocationModels);
2181 cg.relocation_model = None;
2182 }
2183 if cg.code_model.as_ref().map_or(false, |s| s == "help") {
2184 prints.push(PrintRequest::CodeModels);
2185 cg.code_model = None;
2186 }
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582187 if dopts
Santiago Pastorino52a47d42018-03-06 05:29:032188 .tls_model
2189 .as_ref()
2190 .map_or(false, |s| s == "help")
2191 {
Amanieu d'Antrasb233a6e2017-10-31 18:24:042192 prints.push(PrintRequest::TlsModels);
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582193 dopts.tls_model = None;
Amanieu d'Antrasb233a6e2017-10-31 18:24:042194 }
Cameron Harte1efa322016-07-10 14:22:132195
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582196 prints.extend(matches.opt_strs("print").into_iter().map(|s| match &*s {
2197 "crate-name" => PrintRequest::CrateName,
2198 "file-names" => PrintRequest::FileNames,
2199 "sysroot" => PrintRequest::Sysroot,
2200 "cfg" => PrintRequest::Cfg,
2201 "target-list" => PrintRequest::TargetList,
2202 "target-cpus" => PrintRequest::TargetCPUs,
2203 "target-features" => PrintRequest::TargetFeatures,
2204 "relocation-models" => PrintRequest::RelocationModels,
2205 "code-models" => PrintRequest::CodeModels,
2206 "tls-models" => PrintRequest::TlsModels,
2207 "native-static-libs" => PrintRequest::NativeStaticLibs,
2208 "target-spec-json" => {
2209 if is_unstable_enabled {
2210 PrintRequest::TargetSpec
2211 } else {
2212 early_error(
2213 error_format,
2214 "the `-Z unstable-options` flag must also be passed to \
2215 enable the target-spec-json print option",
2216 );
2217 }
2218 }
2219 req => early_error(error_format, &format!("unknown print request `{}`", req)),
2220 }));
Alex Crichton117984b2014-12-16 00:03:392221
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582222 prints
2223}
2224
2225fn parse_target_triple(matches: &getopts::Matches, error_format: ErrorOutputType) -> TargetTriple {
2226 match matches.opt_str("target") {
2227 Some(target) if target.ends_with(".json") => {
Philipp Oppermann7b491902018-03-24 19:14:592228 let path = Path::new(&target);
ljedrz0b2e9f72018-10-10 13:33:102229 TargetTriple::from_path(&path).unwrap_or_else(|_|
2230 early_error(error_format, &format!("target file {:?} does not exist", path)))
Philipp Oppermann3908b2e2018-03-14 14:27:062231 }
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582232 Some(target) => TargetTriple::TargetTriple(target),
2233 _ => TargetTriple::from_triple(host_triple()),
2234 }
2235}
2236
2237fn parse_opt_level(
2238 matches: &getopts::Matches,
2239 cg: &CodegenOptions,
2240 error_format: ErrorOutputType,
2241) -> OptLevel {
2242 // The `-O` and `-C opt-level` flags specify the same setting, so we want to be able
2243 // to use them interchangeably. However, because they're technically different flags,
2244 // we need to work out manually which should take precedence if both are supplied (i.e.
2245 // the rightmost flag). We do this by finding the (rightmost) position of both flags and
2246 // comparing them. Note that if a flag is not found, its position will be `None`, which
2247 // always compared less than `Some(_)`.
2248 let max_o = matches.opt_positions("O").into_iter().max();
2249 let max_c = matches.opt_strs_pos("C").into_iter().flat_map(|(i, s)| {
2250 if let Some("opt-level") = s.splitn(2, '=').next() {
2251 Some(i)
2252 } else {
2253 None
2254 }
2255 }).max();
2256 if max_o > max_c {
2257 OptLevel::Default
Philipp Oppermann3908b2e2018-03-14 14:27:062258 } else {
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582259 match cg.opt_level.as_ref().map(String::as_ref) {
2260 None => OptLevel::No,
2261 Some("0") => OptLevel::No,
2262 Some("1") => OptLevel::Less,
2263 Some("2") => OptLevel::Default,
2264 Some("3") => OptLevel::Aggressive,
2265 Some("s") => OptLevel::Size,
2266 Some("z") => OptLevel::SizeMin,
2267 Some(arg) => {
2268 early_error(
2269 error_format,
2270 &format!(
2271 "optimization level needs to be \
2272 between 0-3, s or z (instead was `{}`)",
2273 arg
2274 ),
2275 );
Alex Crichton117984b2014-12-16 00:03:392276 }
Nick Cameron37ca3672014-05-06 11:38:012277 }
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582278 }
2279}
2280
2281fn select_debuginfo(
2282 matches: &getopts::Matches,
2283 cg: &CodegenOptions,
2284 error_format: ErrorOutputType,
2285) -> DebugInfo {
varkore8e43c92019-04-30 20:52:052286 let max_g = matches.opt_positions("g").into_iter().max();
2287 let max_c = matches.opt_strs_pos("C").into_iter().flat_map(|(i, s)| {
2288 if let Some("debuginfo") = s.splitn(2, '=').next() {
2289 Some(i)
2290 } else {
2291 None
Alex Crichton117984b2014-12-16 00:03:392292 }
varkore8e43c92019-04-30 20:52:052293 }).max();
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582294 if max_g > max_c {
Mark Rousskov2bc71972018-07-26 17:41:102295 DebugInfo::Full
Nick Cameron37ca3672014-05-06 11:38:012296 } else {
Alex Crichton117984b2014-12-16 00:03:392297 match cg.debuginfo {
Mark Rousskov2bc71972018-07-26 17:41:102298 None | Some(0) => DebugInfo::None,
2299 Some(1) => DebugInfo::Limited,
2300 Some(2) => DebugInfo::Full,
Alex Crichton117984b2014-12-16 00:03:392301 Some(arg) => {
Santiago Pastorino52a47d42018-03-06 05:29:032302 early_error(
2303 error_format,
2304 &format!(
2305 "debug info level needs to be between \
2306 0-2 (instead was `{}`)",
2307 arg
2308 ),
2309 );
Alex Crichton117984b2014-12-16 00:03:392310 }
2311 }
Alex Crichtond085d9d2014-12-16 22:32:022312 }
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582313}
Nick Cameron37ca3672014-05-06 11:38:012314
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582315fn parse_libs(
2316 matches: &getopts::Matches,
2317 error_format: ErrorOutputType,
2318) -> Vec<(String, Option<String>, Option<cstore::NativeLibraryKind>)> {
2319 matches
Santiago Pastorino52a47d42018-03-06 05:29:032320 .opt_strs("l")
2321 .into_iter()
2322 .map(|s| {
2323 // Parse string of the form "[KIND=]lib[:new_name]",
2324 // where KIND is one of "dylib", "framework", "static".
2325 let mut parts = s.splitn(2, '=');
2326 let kind = parts.next().unwrap();
2327 let (name, kind) = match (parts.next(), kind) {
2328 (None, name) => (name, None),
2329 (Some(name), "dylib") => (name, Some(cstore::NativeUnknown)),
2330 (Some(name), "framework") => (name, Some(cstore::NativeFramework)),
2331 (Some(name), "static") => (name, Some(cstore::NativeStatic)),
2332 (Some(name), "static-nobundle") => (name, Some(cstore::NativeStaticNobundle)),
2333 (_, s) => {
2334 early_error(
2335 error_format,
2336 &format!(
2337 "unknown library kind `{}`, expected \
2338 one of dylib, framework, or static",
2339 s
2340 ),
2341 );
2342 }
2343 };
2344 if kind == Some(cstore::NativeStaticNobundle) && !nightly_options::is_nightly_build() {
2345 early_error(
2346 error_format,
2347 &format!(
2348 "the library kind 'static-nobundle' is only \
2349 accepted on the nightly compiler"
2350 ),
2351 );
Alex Crichton8e6e8462014-10-21 06:04:162352 }
Santiago Pastorino52a47d42018-03-06 05:29:032353 let mut name_parts = name.splitn(2, ':');
2354 let name = name_parts.next().unwrap();
2355 let new_name = name_parts.next();
ljedrze5eb5382018-10-10 13:34:072356 (name.to_owned(), new_name.map(|n| n.to_owned()), kind)
Santiago Pastorino52a47d42018-03-06 05:29:032357 })
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582358 .collect()
2359}
Alex Crichton8e6e8462014-10-21 06:04:162360
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582361fn parse_borrowck_mode(dopts: &DebuggingOptions, error_format: ErrorOutputType) -> BorrowckMode {
2362 match dopts.borrowck.as_ref().map(|s| &s[..]) {
Matthew Jasperaa6fb6c2019-01-26 17:25:372363 None | Some("migrate") => BorrowckMode::Migrate,
est31c9af68e2017-11-19 22:35:532364 Some("mir") => BorrowckMode::Mir,
Santiago Pastorino52a47d42018-03-06 05:29:032365 Some(m) => early_error(error_format, &format!("unknown borrowck mode `{}`", m)),
Keegan McAllisterad9a1da2014-09-12 15:17:582366 }
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582367}
Keegan McAllisterad9a1da2014-09-12 15:17:582368
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582369fn parse_externs(
2370 matches: &getopts::Matches,
2371 debugging_opts: &DebuggingOptions,
2372 error_format: ErrorOutputType,
2373 is_unstable_enabled: bool,
2374) -> Externs {
Aaron Hill48ec29d2019-01-30 20:33:502375 if matches.opt_present("extern-private") && !debugging_opts.unstable_options {
2376 early_error(
2377 ErrorOutputType::default(),
2378 "'--extern-private' is unstable and only \
2379 available for nightly builds of rustc."
2380 )
2381 }
2382
Alexander Regueiroc1d29ee2019-09-06 02:57:442383 // We start out with a `Vec<(Option<String>, bool)>>`,
2384 // and later convert it into a `BTreeSet<(Option<String>, bool)>`
Aaron Hill7cc3ce32019-03-25 03:06:322385 // This allows to modify entries in-place to set their correct
Alexander Regueiroc1d29ee2019-09-06 02:57:442386 // 'public' value.
Aaron Hill482b77a2019-04-07 22:48:402387 let mut externs: BTreeMap<String, ExternEntry> = BTreeMap::new();
2388 for (arg, private) in matches.opt_strs("extern").into_iter().map(|v| (v, false))
2389 .chain(matches.opt_strs("extern-private").into_iter().map(|v| (v, true))) {
Aaron Hill7cc3ce32019-03-25 03:06:322390
Alex Crichtone98dce32015-04-01 18:28:342391 let mut parts = arg.splitn(2, '=');
ljedrz0b2e9f72018-10-10 13:33:102392 let name = parts.next().unwrap_or_else(||
2393 early_error(error_format, "--extern value must not be empty"));
Eduard-Mihai Burtescu26b1ed12018-08-24 15:51:102394 let location = parts.next().map(|s| s.to_string());
Alexis Beingessnerfe8a4132014-09-18 21:05:522395
Aaron Hill4dfce342019-04-09 21:24:242396 let entry = externs
ljedrze5eb5382018-10-10 13:34:072397 .entry(name.to_owned())
Aaron Hill4dfce342019-04-09 21:24:242398 .or_default();
Alex Crichtoncc3c8bb2014-07-01 15:37:542399
Aaron Hill482b77a2019-04-07 22:48:402400
Aaron Hill4dfce342019-04-09 21:24:242401 entry.locations.insert(location.clone());
2402
2403 // Crates start out being not private,
2404 // and go to being private if we see an '--extern-private'
2405 // flag
2406 entry.is_private_dep |= private;
Aaron Hill482b77a2019-04-07 22:48:402407 }
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582408 Externs(externs)
2409}
Aaron Hill7cc3ce32019-03-25 03:06:322410
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582411fn parse_remap_path_prefix(
2412 matches: &getopts::Matches,
2413 error_format: ErrorOutputType
2414) -> Vec<(PathBuf, PathBuf)> {
2415 matches
Santiago Pastorino52a47d42018-03-06 05:29:032416 .opt_strs("remap-path-prefix")
Jeremy Fitzhardinge56a68282018-02-18 23:05:242417 .into_iter()
2418 .map(|remap| {
2419 let mut parts = remap.rsplitn(2, '='); // reverse iterator
2420 let to = parts.next();
2421 let from = parts.next();
2422 match (from, to) {
2423 (Some(from), Some(to)) => (PathBuf::from(from), PathBuf::from(to)),
Santiago Pastorino52a47d42018-03-06 05:29:032424 _ => early_error(
2425 error_format,
2426 "--remap-path-prefix must contain '=' between FROM and TO",
2427 ),
Jeremy Fitzhardinge56a68282018-02-18 23:05:242428 }
2429 })
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582430 .collect()
2431}
Jeremy Fitzhardinge56a68282018-02-18 23:05:242432
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582433pub fn build_session_options(matches: &getopts::Matches) -> Options {
2434 let color = parse_color(matches);
2435
2436 let edition = parse_crate_edition(matches);
2437
2438 let (json_rendered, json_artifact_notifications) = parse_json(matches);
2439
2440 let error_format = parse_error_format(matches, color, json_rendered);
2441
2442 let unparsed_crate_types = matches.opt_strs("crate-type");
2443 let crate_types = parse_crate_types_from_list(unparsed_crate_types)
2444 .unwrap_or_else(|e| early_error(error_format, &e[..]));
2445
2446 let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(matches, error_format);
2447
2448 let mut debugging_opts = build_debugging_options(matches, error_format);
2449 check_debug_option_stability(&debugging_opts, error_format, json_rendered);
2450
2451 let output_types = parse_output_types(&debugging_opts, matches, error_format);
2452
2453 let mut cg = build_codegen_options(matches, error_format);
2454 let (disable_thinlto, codegen_units) = should_override_cgus_and_disable_thinlto(
2455 &output_types,
2456 matches,
2457 error_format,
2458 cg.codegen_units,
2459 );
2460
2461 check_thread_count(&debugging_opts, error_format);
2462
2463 let incremental = select_incremental_path(&debugging_opts, &cg, error_format);
2464
2465 if debugging_opts.profile && incremental.is_some() {
2466 early_error(
Santiago Pastorino52a47d42018-03-06 05:29:032467 error_format,
Mazdak Farrokhzad9d766ed2019-10-11 21:30:582468 "can't instrument with gcov profiling when compiling incrementally",
2469 );
2470 }
2471
2472 if cg.profile_generate.enabled() && cg.profile_use.is_some() {
2473 early_error(
2474 error_format,
2475 "options `-C profile-generate` and `-C profile-use` are exclusive",
2476 );
2477 }
2478
2479 let is_unstable_enabled = nightly_options::is_unstable_enabled(matches);
2480 let prints = collect_print_requests(
2481 &mut cg,
2482 &mut debugging_opts,
2483 matches,
2484 is_unstable_enabled,
2485 error_format,
2486 );
2487
2488 let cg = cg;
2489
2490 let sysroot_opt = matches.opt_str("sysroot").map(|m| PathBuf::from(&m));
2491 let target_triple = parse_target_triple(matches, error_format);
2492 let opt_level = parse_opt_level(matches, &cg, error_format);
2493 // The `-g` and `-C debuginfo` flags specify the same setting, so we want to be able
2494 // to use them interchangeably. See the note above (regarding `-O` and `-C opt-level`)
2495 // for more details.
2496 let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
2497 let debuginfo = select_debuginfo(matches, &cg, error_format);
2498
2499 let mut search_paths = vec![];
2500 for s in &matches.opt_strs("L") {
2501 search_paths.push(SearchPath::from_cli_opt(&s[..], error_format));
2502 }
2503
2504 let libs = parse_libs(matches, error_format);
2505
2506 let test = matches.opt_present("test");
2507
2508 let borrowck_mode = parse_borrowck_mode(&debugging_opts, error_format);
2509
2510 if !cg.remark.is_empty() && debuginfo == DebugInfo::None {
2511 early_warn(
2512 error_format,
2513 "-C remark requires \"-C debuginfo=n\" to show source locations",
2514 );
2515 }
2516
2517 let externs = parse_externs(matches, &debugging_opts, error_format, is_unstable_enabled);
2518
2519 let crate_name = matches.opt_str("crate-name");
2520
2521 let remap_path_prefix = parse_remap_path_prefix(matches, error_format);
2522
2523 Options {
2524 crate_types,
2525 optimize: opt_level,
2526 debuginfo,
2527 lint_opts,
2528 lint_cap,
2529 describe_lints,
2530 output_types,
2531 search_paths,
2532 maybe_sysroot: sysroot_opt,
2533 target_triple,
2534 test,
2535 incremental,
2536 debugging_opts,
2537 prints,
2538 borrowck_mode,
2539 cg,
2540 error_format,
2541 externs,
2542 crate_name,
2543 alt_std_name: None,
2544 libs,
2545 unstable_features: UnstableFeatures::from_environment(),
2546 debug_assertions,
2547 actually_rustdoc: false,
2548 cli_forced_codegen_units: codegen_units,
2549 cli_forced_thinlto_off: disable_thinlto,
2550 remap_path_prefix,
2551 edition,
2552 json_artifact_notifications,
2553 }
Nick Cameroncacd6b62015-01-30 08:44:272554}
2555
Aaron Hill14986082019-07-20 20:34:412556pub fn make_crate_type_option() -> RustcOptGroup {
2557 opt::multi_s(
2558 "",
2559 "crate-type",
2560 "Comma separated list of types of crates
2561 for the compiler to emit",
2562 "[bin|lib|rlib|dylib|cdylib|staticlib|proc-macro]",
2563 )
2564}
2565
Santiago Pastorino52a47d42018-03-06 05:29:032566pub fn parse_crate_types_from_list(list_list: Vec<String>) -> Result<Vec<CrateType>, String> {
Brian Anderson1c3655b2014-07-20 04:11:262567 let mut crate_types: Vec<CrateType> = Vec::new();
Jorge Apariciod5d7e652015-01-31 17:20:462568 for unparsed_crate_type in &list_list {
Jorge Aparicio00f3c3f2014-11-27 18:53:342569 for part in unparsed_crate_type.split(',') {
Brian Anderson1c3655b2014-07-20 04:11:262570 let new_part = match part {
Santiago Pastorino52a47d42018-03-06 05:29:032571 "lib" => default_lib_output(),
Mark Rousskov2a934422018-07-26 17:13:112572 "rlib" => CrateType::Rlib,
2573 "staticlib" => CrateType::Staticlib,
2574 "dylib" => CrateType::Dylib,
2575 "cdylib" => CrateType::Cdylib,
2576 "bin" => CrateType::Executable,
2577 "proc-macro" => CrateType::ProcMacro,
ljedrz942a7962018-10-10 13:24:312578 _ => return Err(format!("unknown crate type: `{}`", part))
Brian Anderson1c3655b2014-07-20 04:11:262579 };
Simonas Kazlauskasa6e84962015-02-09 17:30:222580 if !crate_types.contains(&new_part) {
2581 crate_types.push(new_part)
2582 }
Brian Anderson1c3655b2014-07-20 04:11:262583 }
2584 }
2585
Michael Kohl9873acc2017-05-28 06:49:142586 Ok(crate_types)
Brian Anderson1c3655b2014-07-20 04:11:262587}
2588
Guillaume Gomezded701b2016-03-15 08:09:292589pub mod nightly_options {
2590 use getopts;
2591 use syntax::feature_gate::UnstableFeatures;
Tim Neumann3f287ef2016-09-24 17:20:572592 use super::{ErrorOutputType, OptionStability, RustcOptGroup};
Mark Mansie957ed92019-02-05 17:20:452593 use crate::session::early_error;
Guillaume Gomezded701b2016-03-15 08:09:292594
2595 pub fn is_unstable_enabled(matches: &getopts::Matches) -> bool {
Santiago Pastorino52a47d42018-03-06 05:29:032596 is_nightly_build()
2597 && matches
2598 .opt_strs("Z")
2599 .iter()
2600 .any(|x| *x == "unstable-options")
Guillaume Gomezded701b2016-03-15 08:09:292601 }
2602
Brandon Edens49d28252016-04-29 06:04:452603 pub fn is_nightly_build() -> bool {
Tim Neumannba838dc2016-09-24 17:19:172604 UnstableFeatures::from_environment().is_nightly_build()
Guillaume Gomezded701b2016-03-15 08:09:292605 }
2606
2607 pub fn check_nightly_options(matches: &getopts::Matches, flags: &[RustcOptGroup]) {
Santiago Pastorino52a47d42018-03-06 05:29:032608 let has_z_unstable_option = matches
2609 .opt_strs("Z")
2610 .iter()
2611 .any(|x| *x == "unstable-options");
2612 let really_allows_unstable_options =
2613 UnstableFeatures::from_environment().is_nightly_build();
Guillaume Gomezded701b2016-03-15 08:09:292614
2615 for opt in flags.iter() {
2616 if opt.stability == OptionStability::Stable {
Santiago Pastorino52a47d42018-03-06 05:29:032617 continue;
Guillaume Gomezded701b2016-03-15 08:09:292618 }
Alex Crichton5c3d0e62017-06-08 21:20:552619 if !matches.opt_present(opt.name) {
Santiago Pastorino52a47d42018-03-06 05:29:032620 continue;
Guillaume Gomezded701b2016-03-15 08:09:292621 }
Alex Crichton5c3d0e62017-06-08 21:20:552622 if opt.name != "Z" && !has_z_unstable_option {
Santiago Pastorino52a47d42018-03-06 05:29:032623 early_error(
2624 ErrorOutputType::default(),
2625 &format!(
2626 "the `-Z unstable-options` flag must also be passed to enable \
2627 the flag `{}`",
2628 opt.name
2629 ),
2630 );
Guillaume Gomezded701b2016-03-15 08:09:292631 }
2632 if really_allows_unstable_options {
Santiago Pastorino52a47d42018-03-06 05:29:032633 continue;
Guillaume Gomezded701b2016-03-15 08:09:292634 }
2635 match opt.stability {
2636 OptionStability::Unstable => {
Santiago Pastorino52a47d42018-03-06 05:29:032637 let msg = format!(
2638 "the option `{}` is only accepted on the \
2639 nightly compiler",
2640 opt.name
2641 );
Guillaume Gomezded701b2016-03-15 08:09:292642 early_error(ErrorOutputType::default(), &msg);
2643 }
Guillaume Gomezded701b2016-03-15 08:09:292644 OptionStability::Stable => {}
2645 }
2646 }
2647 }
2648}
2649
Alex Crichton3cb9fa22015-01-20 23:45:072650impl fmt::Display for CrateType {
Zack M. Davis5b22d9b2018-08-30 05:02:422651 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
Valerii Hiora70a79a92014-06-11 07:48:172652 match *self {
Mark Rousskov2a934422018-07-26 17:13:112653 CrateType::Executable => "bin".fmt(f),
2654 CrateType::Dylib => "dylib".fmt(f),
2655 CrateType::Rlib => "rlib".fmt(f),
2656 CrateType::Staticlib => "staticlib".fmt(f),
2657 CrateType::Cdylib => "cdylib".fmt(f),
2658 CrateType::ProcMacro => "proc-macro".fmt(f),
Valerii Hiora70a79a92014-06-11 07:48:172659 }
2660 }
2661}
Nick Cameron37ca3672014-05-06 11:38:012662
Andy Russell4e35cbb22018-11-12 18:05:202663/// Command-line arguments passed to the compiler have to be incorporated with
Michael Woerister32414312016-08-02 20:53:582664/// the dependency tracking system for incremental compilation. This module
2665/// provides some utilities to make this more convenient.
2666///
Andy Russell4e35cbb22018-11-12 18:05:202667/// The values of all command-line arguments that are relevant for dependency
Michael Woerister32414312016-08-02 20:53:582668/// tracking are hashed into a single value that determines whether the
2669/// incremental compilation cache can be re-used or not. This hashing is done
Alexander Regueiroc1d29ee2019-09-06 02:57:442670/// via the `DepTrackingHash` trait defined below, since the standard `Hash`
2671/// implementation might not be suitable (e.g., arguments are stored in a `Vec`,
Michael Woerister32414312016-08-02 20:53:582672/// the hash of which is order dependent, but we might not want the order of
2673/// arguments to make a difference for the hash).
2674///
Alexander Regueiroc1d29ee2019-09-06 02:57:442675/// However, since the value provided by `Hash::hash` often *is* suitable,
Michael Woerister32414312016-08-02 20:53:582676/// especially for primitive types, there is the
Alexander Regueiroc1d29ee2019-09-06 02:57:442677/// `impl_dep_tracking_hash_via_hash!()` macro that allows to simply reuse the
2678/// `Hash` implementation for `DepTrackingHash`. It's important though that
Michael Woerister32414312016-08-02 20:53:582679/// we have an opt-in scheme here, so one is hopefully forced to think about
Andy Russell4e35cbb22018-11-12 18:05:202680/// how the hash should be calculated when adding a new command-line argument.
Michael Woerister32414312016-08-02 20:53:582681mod dep_tracking {
Mark Mansie957ed92019-02-05 17:20:452682 use crate::lint;
2683 use crate::middle::cstore;
Michael Woerister32414312016-08-02 20:53:582684 use std::collections::BTreeMap;
Alex Crichton10c31342016-09-29 00:23:362685 use std::hash::Hash;
Michael Woerister32414312016-08-02 20:53:582686 use std::path::PathBuf;
Alex Crichton10c31342016-09-29 00:23:362687 use std::collections::hash_map::DefaultHasher;
Michael Woerister24093a62018-09-04 15:57:172688 use super::{CrateType, DebugInfo, ErrorOutputType, OptLevel, OutputTypes,
Eduard-Mihai Burtescu20929632019-01-29 05:24:322689 Passes, Sanitizer, LtoCli, LinkerPluginLto, SwitchWithOptPath,
2690 SymbolManglingVersion};
Peter Jinb91d2112018-12-31 18:58:132691 use rustc_target::spec::{MergeFunctions, PanicStrategy, RelroLevel, TargetTriple};
Kurtis Nusbaum320fdaa2018-04-20 04:03:212692 use syntax::edition::Edition;
Alexander Regueiroc1d29ee2019-09-06 02:57:442693 use syntax::feature_gate::UnstableFeatures;
Michael Woerister32414312016-08-02 20:53:582694
2695 pub trait DepTrackingHash {
est31d2908492017-05-02 03:55:202696 fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType);
Michael Woerister32414312016-08-02 20:53:582697 }
2698
2699 macro_rules! impl_dep_tracking_hash_via_hash {
2700 ($t:ty) => (
2701 impl DepTrackingHash for $t {
Alex Crichton10c31342016-09-29 00:23:362702 fn hash(&self, hasher: &mut DefaultHasher, _: ErrorOutputType) {
Michael Woerister32414312016-08-02 20:53:582703 Hash::hash(self, hasher);
2704 }
2705 }
2706 )
2707 }
2708
2709 macro_rules! impl_dep_tracking_hash_for_sortable_vec_of {
2710 ($t:ty) => (
2711 impl DepTrackingHash for Vec<$t> {
Alex Crichton10c31342016-09-29 00:23:362712 fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType) {
Michael Woeristera7de0bc2016-08-09 19:28:242713 let mut elems: Vec<&$t> = self.iter().collect();
Michael Woerister32414312016-08-02 20:53:582714 elems.sort();
Michael Woeristera7de0bc2016-08-09 19:28:242715 Hash::hash(&elems.len(), hasher);
2716 for (index, elem) in elems.iter().enumerate() {
2717 Hash::hash(&index, hasher);
2718 DepTrackingHash::hash(*elem, hasher, error_format);
Michael Woerister32414312016-08-02 20:53:582719 }
2720 }
2721 }
2722 );
2723 }
2724
2725 impl_dep_tracking_hash_via_hash!(bool);
2726 impl_dep_tracking_hash_via_hash!(usize);
Austin Hicks63ebf082017-03-08 21:28:472727 impl_dep_tracking_hash_via_hash!(u64);
Michael Woerister32414312016-08-02 20:53:582728 impl_dep_tracking_hash_via_hash!(String);
Oliver Schneiderd732da82017-12-14 07:09:192729 impl_dep_tracking_hash_via_hash!(PathBuf);
Michael Woerister32414312016-08-02 20:53:582730 impl_dep_tracking_hash_via_hash!(lint::Level);
2731 impl_dep_tracking_hash_via_hash!(Option<bool>);
2732 impl_dep_tracking_hash_via_hash!(Option<usize>);
2733 impl_dep_tracking_hash_via_hash!(Option<String>);
Austin Hicks63ebf082017-03-08 21:28:472734 impl_dep_tracking_hash_via_hash!(Option<(String, u64)>);
Aaron Hillfe15f712019-01-29 21:10:492735 impl_dep_tracking_hash_via_hash!(Option<Vec<String>>);
Peter Jinb91d2112018-12-31 18:58:132736 impl_dep_tracking_hash_via_hash!(Option<MergeFunctions>);
Jorge Apariciocbb967f2016-09-28 02:26:082737 impl_dep_tracking_hash_via_hash!(Option<PanicStrategy>);
Johannes Löthberg94b9cc92017-07-14 20:01:372738 impl_dep_tracking_hash_via_hash!(Option<RelroLevel>);
Michael Woerister32414312016-08-02 20:53:582739 impl_dep_tracking_hash_via_hash!(Option<lint::Level>);
2740 impl_dep_tracking_hash_via_hash!(Option<PathBuf>);
Peter Wagenetae32b6e2017-02-21 21:18:582741 impl_dep_tracking_hash_via_hash!(Option<cstore::NativeLibraryKind>);
Michael Woerister32414312016-08-02 20:53:582742 impl_dep_tracking_hash_via_hash!(CrateType);
Peter Jinb91d2112018-12-31 18:58:132743 impl_dep_tracking_hash_via_hash!(MergeFunctions);
Michael Woerister32414312016-08-02 20:53:582744 impl_dep_tracking_hash_via_hash!(PanicStrategy);
Johannes Löthberg94b9cc92017-07-14 20:01:372745 impl_dep_tracking_hash_via_hash!(RelroLevel);
Michael Woerister32414312016-08-02 20:53:582746 impl_dep_tracking_hash_via_hash!(Passes);
2747 impl_dep_tracking_hash_via_hash!(OptLevel);
Michael Woerister24093a62018-09-04 15:57:172748 impl_dep_tracking_hash_via_hash!(LtoCli);
Mark Rousskov2bc71972018-07-26 17:41:102749 impl_dep_tracking_hash_via_hash!(DebugInfo);
Michael Woerister32414312016-08-02 20:53:582750 impl_dep_tracking_hash_via_hash!(UnstableFeatures);
Michael Woerister32414312016-08-02 20:53:582751 impl_dep_tracking_hash_via_hash!(OutputTypes);
2752 impl_dep_tracking_hash_via_hash!(cstore::NativeLibraryKind);
Jorge Aparicio0b06db52017-02-21 03:34:422753 impl_dep_tracking_hash_via_hash!(Sanitizer);
2754 impl_dep_tracking_hash_via_hash!(Option<Sanitizer>);
Philipp Oppermann3908b2e2018-03-14 14:27:062755 impl_dep_tracking_hash_via_hash!(TargetTriple);
Kurtis Nusbaum320fdaa2018-04-20 04:03:212756 impl_dep_tracking_hash_via_hash!(Edition);
Michael Woerister04f425d2019-02-01 14:15:432757 impl_dep_tracking_hash_via_hash!(LinkerPluginLto);
Michael Woerister64ee32e2019-05-28 14:13:592758 impl_dep_tracking_hash_via_hash!(SwitchWithOptPath);
Eduard-Mihai Burtescu20929632019-01-29 05:24:322759 impl_dep_tracking_hash_via_hash!(SymbolManglingVersion);
Michael Woerister32414312016-08-02 20:53:582760
2761 impl_dep_tracking_hash_for_sortable_vec_of!(String);
Oliver Schneiderd732da82017-12-14 07:09:192762 impl_dep_tracking_hash_for_sortable_vec_of!(PathBuf);
Michael Woerister32414312016-08-02 20:53:582763 impl_dep_tracking_hash_for_sortable_vec_of!(CrateType);
2764 impl_dep_tracking_hash_for_sortable_vec_of!((String, lint::Level));
Santiago Pastorino52a47d42018-03-06 05:29:032765 impl_dep_tracking_hash_for_sortable_vec_of!((
2766 String,
2767 Option<String>,
2768 Option<cstore::NativeLibraryKind>
2769 ));
Austin Hicks63ebf082017-03-08 21:28:472770 impl_dep_tracking_hash_for_sortable_vec_of!((String, u64));
Michael Woerister32414312016-08-02 20:53:582771
Michael Woerister32414312016-08-02 20:53:582772 impl<T1, T2> DepTrackingHash for (T1, T2)
Santiago Pastorino52a47d42018-03-06 05:29:032773 where
2774 T1: DepTrackingHash,
2775 T2: DepTrackingHash,
Michael Woerister32414312016-08-02 20:53:582776 {
Alex Crichton10c31342016-09-29 00:23:362777 fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType) {
Michael Woerister32414312016-08-02 20:53:582778 Hash::hash(&0, hasher);
2779 DepTrackingHash::hash(&self.0, hasher, error_format);
2780 Hash::hash(&1, hasher);
2781 DepTrackingHash::hash(&self.1, hasher, error_format);
2782 }
2783 }
2784
Vadim Chugunov13477c72016-11-24 00:09:512785 impl<T1, T2, T3> DepTrackingHash for (T1, T2, T3)
Santiago Pastorino52a47d42018-03-06 05:29:032786 where
2787 T1: DepTrackingHash,
2788 T2: DepTrackingHash,
2789 T3: DepTrackingHash,
Vadim Chugunov13477c72016-11-24 00:09:512790 {
2791 fn hash(&self, hasher: &mut DefaultHasher, error_format: ErrorOutputType) {
2792 Hash::hash(&0, hasher);
2793 DepTrackingHash::hash(&self.0, hasher, error_format);
2794 Hash::hash(&1, hasher);
2795 DepTrackingHash::hash(&self.1, hasher, error_format);
2796 Hash::hash(&2, hasher);
2797 DepTrackingHash::hash(&self.2, hasher, error_format);
2798 }
2799 }
2800
Michael Woerister32414312016-08-02 20:53:582801 // This is a stable hash because BTreeMap is a sorted container
Santiago Pastorino52a47d42018-03-06 05:29:032802 pub fn stable_hash(
2803 sub_hashes: BTreeMap<&'static str, &dyn DepTrackingHash>,
2804 hasher: &mut DefaultHasher,
2805 error_format: ErrorOutputType,
2806 ) {
Michael Woerister32414312016-08-02 20:53:582807 for (key, sub_hash) in sub_hashes {
2808 // Using Hash::hash() instead of DepTrackingHash::hash() is fine for
2809 // the keys, as they are just plain strings
2810 Hash::hash(&key.len(), hasher);
2811 Hash::hash(key, hasher);
2812 sub_hash.hash(hasher, error_format);
2813 }
2814 }
2815}