1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! Contains infrastructure for configuring the compiler, including parsing
12 //! command line options.
14 pub use self::EntryFnType
::*;
15 pub use self::CrateType
::*;
16 pub use self::Passes
::*;
17 pub use self::DebugInfoLevel
::*;
19 use session
::{early_error, early_warn, Session}
;
20 use session
::search_paths
::SearchPaths
;
22 use rustc_back
::target
::Target
;
26 use syntax
::ast
::{self, IntTy, UintTy}
;
28 use syntax
::attr
::AttrMetaMethods
;
30 use syntax
::parse
::token
::InternedString
;
31 use syntax
::feature_gate
::UnstableFeatures
;
33 use errors
::{ColorConfig, FatalError, Handler}
;
36 use std
::collections
::{BTreeMap, BTreeSet}
;
37 use std
::collections
::btree_map
::Iter
as BTreeMapIter
;
38 use std
::collections
::btree_map
::Keys
as BTreeMapKeysIter
;
39 use std
::collections
::btree_map
::Values
as BTreeMapValuesIter
;
43 use std
::hash
::{Hasher, SipHasher}
;
44 use std
::iter
::FromIterator
;
45 use std
::path
::PathBuf
;
50 pub uint_type
: UintTy
,
53 #[derive(Clone, Copy, PartialEq, Hash)]
63 #[derive(Clone, Copy, PartialEq, Hash)]
64 pub enum DebugInfoLevel
{
70 #[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, PartialOrd, Ord,
71 RustcEncodable
, RustcDecodable
)]
81 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
82 pub enum ErrorOutputType
{
83 HumanReadable(ColorConfig
),
87 impl Default
for ErrorOutputType
{
88 fn default() -> ErrorOutputType
{
89 ErrorOutputType
::HumanReadable(ColorConfig
::Auto
)
94 fn is_compatible_with_codegen_units_and_single_output_file(&self) -> bool
{
97 OutputType
::DepInfo
=> true,
99 OutputType
::Assembly
|
100 OutputType
::LlvmAssembly
|
101 OutputType
::Object
=> false,
105 fn shorthand(&self) -> &'
static str {
107 OutputType
::Bitcode
=> "llvm-bc",
108 OutputType
::Assembly
=> "asm",
109 OutputType
::LlvmAssembly
=> "llvm-ir",
110 OutputType
::Object
=> "obj",
111 OutputType
::Exe
=> "link",
112 OutputType
::DepInfo
=> "dep-info",
116 pub fn extension(&self) -> &'
static str {
118 OutputType
::Bitcode
=> "bc",
119 OutputType
::Assembly
=> "s",
120 OutputType
::LlvmAssembly
=> "ll",
121 OutputType
::Object
=> "o",
122 OutputType
::DepInfo
=> "d",
123 OutputType
::Exe
=> "",
128 // Use tree-based collections to cheaply get a deterministic Hash implementation.
129 // DO NOT switch BTreeMap out for an unsorted container type! That would break
130 // dependency tracking for commandline arguments.
131 #[derive(Clone, Hash)]
132 pub struct OutputTypes(BTreeMap
<OutputType
, Option
<PathBuf
>>);
135 pub fn new(entries
: &[(OutputType
, Option
<PathBuf
>)]) -> OutputTypes
{
136 OutputTypes(BTreeMap
::from_iter(entries
.iter()
137 .map(|&(k
, ref v
)| (k
, v
.clone()))))
140 pub fn get(&self, key
: &OutputType
) -> Option
<&Option
<PathBuf
>> {
144 pub fn contains_key(&self, key
: &OutputType
) -> bool
{
145 self.0.contains_key(key
)
148 pub fn keys
<'a
>(&'a
self) -> BTreeMapKeysIter
<'a
, OutputType
, Option
<PathBuf
>> {
152 pub fn values
<'a
>(&'a
self) -> BTreeMapValuesIter
<'a
, OutputType
, Option
<PathBuf
>> {
158 // Use tree-based collections to cheaply get a deterministic Hash implementation.
159 // DO NOT switch BTreeMap or BTreeSet out for an unsorted container type! That
160 // would break dependency tracking for commandline arguments.
161 #[derive(Clone, Hash)]
162 pub struct Externs(BTreeMap
<String
, BTreeSet
<String
>>);
165 pub fn new(data
: BTreeMap
<String
, BTreeSet
<String
>>) -> Externs
{
169 pub fn get(&self, key
: &str) -> Option
<&BTreeSet
<String
>> {
173 pub fn iter
<'a
>(&'a
self) -> BTreeMapIter
<'a
, String
, BTreeSet
<String
>> {
178 macro_rules
! hash_option
{
179 ($opt_name
:ident
, $opt_expr
:expr
, $sub_hashes
:expr
, [UNTRACKED
]) => ({}
);
180 ($opt_name
:ident
, $opt_expr
:expr
, $sub_hashes
:expr
, [TRACKED
]) => ({
181 if $sub_hashes
.insert(stringify
!($opt_name
),
182 $opt_expr
as &dep_tracking
::DepTrackingHash
).is_some() {
183 bug
!("Duplicate key in CLI DepTrackingHash: {}", stringify
!($opt_name
))
189 [UNTRACKED_WITH_WARNING $warn_val
:expr
, $warn_text
:expr
, $error_format
:expr
]) => ({
190 if *$opt_expr
== $warn_val
{
191 early_warn($error_format
, $warn_text
)
196 macro_rules
! top_level_options
{
197 (pub struct Options
{ $
(
198 $opt
:ident
: $t
:ty
[$dep_tracking_marker
:ident $
($warn_val
:expr
, $warn_text
:expr
)*],
206 pub fn dep_tracking_hash(&self) -> u64 {
207 let mut sub_hashes
= BTreeMap
::new();
212 [$dep_tracking_marker $
($warn_val
,
214 self.error_format
)*]);
216 let mut hasher
= SipHasher
::new();
217 dep_tracking
::stable_hash(sub_hashes
,
226 // The top-level commandline options struct
228 // For each option, one has to specify how it behaves with regard to the
229 // dependency tracking system of incremental compilation. This is done via the
230 // square-bracketed directive after the field type. The options are:
233 // A change in the given field will cause the compiler to completely clear the
234 // incremental compilation cache before proceeding.
237 // Incremental compilation is not influenced by this option.
239 // [UNTRACKED_WITH_WARNING(val, warning)]
240 // The option is incompatible with incremental compilation in some way. If it
241 // has the value `val`, the string `warning` is emitted as a warning.
243 // If you add a new option to this struct or one of the sub-structs like
244 // CodegenOptions, think about how it influences incremental compilation. If in
245 // doubt, specify [TRACKED], which is always "correct" but might lead to
246 // unnecessary re-compilation.
249 // The crate config requested for the session, which may be combined
250 // with additional crate configurations during the compile process
251 crate_types
: Vec
<CrateType
> [TRACKED
],
252 optimize
: OptLevel
[TRACKED
],
253 // Include the debug_assertions flag into dependency tracking, since it
254 // can influence whether overflow checks are done or not.
255 debug_assertions
: bool
[TRACKED
],
256 debuginfo
: DebugInfoLevel
[TRACKED
],
257 lint_opts
: Vec
<(String
, lint
::Level
)> [TRACKED
],
258 lint_cap
: Option
<lint
::Level
> [TRACKED
],
259 describe_lints
: bool
[UNTRACKED
],
260 output_types
: OutputTypes
[TRACKED
],
261 // FIXME(mw): We track this for now but it actually doesn't make too
262 // much sense: The search path can stay the same while the
263 // things discovered there might have changed on disk.
264 search_paths
: SearchPaths
[TRACKED
],
265 libs
: Vec
<(String
, cstore
::NativeLibraryKind
)> [TRACKED
],
266 maybe_sysroot
: Option
<PathBuf
> [TRACKED
],
268 target_triple
: String
[TRACKED
],
270 test
: bool
[TRACKED
],
271 error_format
: ErrorOutputType
[UNTRACKED
],
272 mir_opt_level
: usize [TRACKED
],
274 // if Some, enable incremental compilation, using the given
275 // directory to store intermediate results
276 incremental
: Option
<PathBuf
> [UNTRACKED
],
278 debugging_opts
: DebuggingOptions
[TRACKED
],
279 prints
: Vec
<PrintRequest
> [UNTRACKED
],
280 cg
: CodegenOptions
[TRACKED
],
281 // FIXME(mw): We track this for now but it actually doesn't make too
282 // much sense: The value of this option can stay the same
283 // while the files they refer to might have changed on disk.
284 externs
: Externs
[TRACKED
],
285 crate_name
: Option
<String
> [TRACKED
],
286 // An optional name to use as the crate for std during std injection,
287 // written `extern crate std = "name"`. Default to "std". Used by
288 // out-of-tree drivers.
289 alt_std_name
: Option
<String
> [TRACKED
],
290 // Indicates how the compiler should treat unstable features
291 unstable_features
: UnstableFeatures
[TRACKED
],
295 #[derive(Clone, PartialEq, Eq)]
296 pub enum PrintRequest
{
309 /// Load source from file
312 /// String that is shown in place of a filename
314 /// Anonymous source string
320 pub fn filestem(&self) -> String
{
322 Input
::File(ref ifile
) => ifile
.file_stem().unwrap()
323 .to_str().unwrap().to_string(),
324 Input
::Str { .. }
=> "rust_out".to_string(),
330 pub struct OutputFilenames
{
331 pub out_directory
: PathBuf
,
332 pub out_filestem
: String
,
333 pub single_output_file
: Option
<PathBuf
>,
335 pub outputs
: OutputTypes
,
338 /// Codegen unit names generated by the numbered naming scheme will contain this
339 /// marker right before the index of the codegen unit.
340 pub const NUMBERED_CODEGEN_UNIT_MARKER
: &'
static str = ".cgu-";
342 impl OutputFilenames
{
343 pub fn path(&self, flavor
: OutputType
) -> PathBuf
{
344 self.outputs
.get(&flavor
).and_then(|p
| p
.to_owned())
345 .or_else(|| self.single_output_file
.clone())
346 .unwrap_or_else(|| self.temp_path(flavor
, None
))
349 /// Get the path where a compilation artifact of the given type for the
350 /// given codegen unit should be placed on disk. If codegen_unit_name is
351 /// None, a path distinct from those of any codegen unit will be generated.
352 pub fn temp_path(&self,
354 codegen_unit_name
: Option
<&str>)
356 let extension
= flavor
.extension();
357 self.temp_path_ext(extension
, codegen_unit_name
)
360 /// Like temp_path, but also supports things where there is no corresponding
361 /// OutputType, like no-opt-bitcode or lto-bitcode.
362 pub fn temp_path_ext(&self,
364 codegen_unit_name
: Option
<&str>)
366 let base
= self.out_directory
.join(&self.filestem());
368 let mut extension
= String
::new();
370 if let Some(codegen_unit_name
) = codegen_unit_name
{
371 if codegen_unit_name
.contains(NUMBERED_CODEGEN_UNIT_MARKER
) {
372 // If we use the numbered naming scheme for modules, we don't want
373 // the files to look like <crate-name><extra>.<crate-name>.<index>.<ext>
374 // but simply <crate-name><extra>.<index>.<ext>
375 let marker_offset
= codegen_unit_name
.rfind(NUMBERED_CODEGEN_UNIT_MARKER
)
377 let index_offset
= marker_offset
+ NUMBERED_CODEGEN_UNIT_MARKER
.len();
378 extension
.push_str(&codegen_unit_name
[index_offset
.. ]);
380 extension
.push_str(codegen_unit_name
);
385 if !extension
.is_empty() {
386 extension
.push_str(".");
389 extension
.push_str(ext
);
392 let path
= base
.with_extension(&extension
[..]);
396 pub fn with_extension(&self, extension
: &str) -> PathBuf
{
397 self.out_directory
.join(&self.filestem()).with_extension(extension
)
400 pub fn filestem(&self) -> String
{
401 format
!("{}{}", self.out_filestem
, self.extra
)
405 pub fn host_triple() -> &'
static str {
406 // Get the host triple out of the build environment. This ensures that our
407 // idea of the host triple is the same as for the set of libraries we've
408 // actually built. We can't just take LLVM's host triple because they
409 // normalize all ix86 architectures to i386.
411 // Instead of grabbing the host triple (for the current host), we grab (at
412 // compile time) the target triple that this rustc is built with and
413 // calling that (at runtime) the host triple.
414 (option_env
!("CFG_COMPILER_HOST_TRIPLE")).
415 expect("CFG_COMPILER_HOST_TRIPLE")
418 /// Some reasonable defaults
419 pub fn basic_options() -> Options
{
421 crate_types
: Vec
::new(),
422 optimize
: OptLevel
::No
,
423 debuginfo
: NoDebugInfo
,
424 lint_opts
: Vec
::new(),
426 describe_lints
: false,
427 output_types
: OutputTypes(BTreeMap
::new()),
428 search_paths
: SearchPaths
::new(),
430 target_triple
: host_triple().to_string(),
434 debugging_opts
: basic_debugging_options(),
436 cg
: basic_codegen_options(),
437 error_format
: ErrorOutputType
::default(),
438 externs
: Externs(BTreeMap
::new()),
442 unstable_features
: UnstableFeatures
::Disallow
,
443 debug_assertions
: true,
448 /// True if there is a reason to build the dep graph.
449 pub fn build_dep_graph(&self) -> bool
{
450 self.incremental
.is_some() ||
451 self.debugging_opts
.dump_dep_graph
||
452 self.debugging_opts
.query_dep_graph
455 pub fn single_codegen_unit(&self) -> bool
{
456 self.incremental
.is_none() ||
457 self.cg
.codegen_units
== 1
461 // The type of entry function, so
462 // users can have their own entry
463 // functions that don't start a
465 #[derive(Copy, Clone, PartialEq)]
466 pub enum EntryFnType
{
472 #[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug)]
481 #[derive(Clone, Hash)]
483 SomePasses(Vec
<String
>),
488 pub fn is_empty(&self) -> bool
{
490 SomePasses(ref v
) => v
.is_empty(),
496 #[derive(Clone, PartialEq, Hash)]
497 pub enum PanicStrategy
{
503 pub fn desc(&self) -> &str {
505 PanicStrategy
::Unwind
=> "unwind",
506 PanicStrategy
::Abort
=> "abort",
511 /// Declare a macro that will define all CodegenOptions/DebuggingOptions fields and parsers all
512 /// at once. The goal of this macro is to define an interface that can be
513 /// programmatically used by the option parser in order to initialize the struct
514 /// without hardcoding field names all over the place.
516 /// The goal is to invoke this macro once with the correct fields, and then this
517 /// macro generates all necessary code. The main gotcha of this macro is the
518 /// cgsetters module which is a bunch of generated code to parse an option into
519 /// its respective field in the struct. There are a few hand-written parsers for
520 /// parsing specific types of values in this module.
521 macro_rules
! options
{
522 ($struct_name
:ident
, $setter_name
:ident
, $defaultfn
:ident
,
523 $buildfn
:ident
, $prefix
:expr
, $outputname
:expr
,
524 $stat
:ident
, $mod_desc
:ident
, $mod_set
:ident
,
525 $
($opt
:ident
: $t
:ty
= (
528 [$dep_tracking_marker
:ident $
(($dep_warn_val
:expr
, $dep_warn_text
:expr
))*],
533 pub struct $struct_name { $(pub $opt: $t),* }
535 pub fn $
defaultfn() -> $struct_name
{
536 $struct_name { $($opt: $init),* }
539 pub fn $
buildfn(matches
: &getopts
::Matches
, error_format
: ErrorOutputType
) -> $struct_name
541 let mut op
= $
defaultfn();
542 for option
in matches
.opt_strs($prefix
) {
543 let mut iter
= option
.splitn(2, '
='
);
544 let key
= iter
.next().unwrap();
545 let value
= iter
.next();
546 let option_to_lookup
= key
.replace("-", "_");
547 let mut found
= false;
548 for &(candidate
, setter
, opt_type_desc
, _
) in $stat
{
549 if option_to_lookup
!= candidate { continue }
550 if !setter(&mut op
, value
) {
551 match (value
, opt_type_desc
) {
552 (Some(..), None
) => {
553 early_error(error_format
, &format
!("{} option `{}` takes no \
554 value", $outputname
, key
))
556 (None
, Some(type_desc
)) => {
557 early_error(error_format
, &format
!("{0} option `{1}` requires \
558 {2} ({3} {1}=<value>)",
562 (Some(value
), Some(type_desc
)) => {
563 early_error(error_format
, &format
!("incorrect value `{}` for {} \
564 option `{}` - {} was expected",
568 (None
, None
) => bug
!()
575 early_error(error_format
, &format
!("unknown {} option: `{}`",
582 impl<'a
> dep_tracking
::DepTrackingHash
for $struct_name
{
584 fn hash(&self, hasher
: &mut SipHasher
, error_format
: ErrorOutputType
) {
585 let mut sub_hashes
= BTreeMap
::new();
590 [$dep_tracking_marker $
($dep_warn_val
,
594 dep_tracking
::stable_hash(sub_hashes
, hasher
, error_format
);
598 pub type $setter_name
= fn(&mut $struct_name
, v
: Option
<&str>) -> bool
;
599 pub const $stat
: &'
static [(&'
static str, $setter_name
,
600 Option
<&'
static str>, &'
static str)] =
601 &[ $
( (stringify
!($opt
), $mod_set
::$opt
, $mod_desc
::$parse
, $desc
) ),* ];
603 #[allow(non_upper_case_globals, dead_code)]
605 pub const parse_bool
: Option
<&'
static str> = None
;
606 pub const parse_opt_bool
: Option
<&'
static str> =
607 Some("one of: `y`, `yes`, `on`, `n`, `no`, or `off`");
608 pub const parse_all_bool
: Option
<&'
static str> =
609 Some("one of: `y`, `yes`, `on`, `n`, `no`, or `off`");
610 pub const parse_string
: Option
<&'
static str> = Some("a string");
611 pub const parse_opt_string
: Option
<&'
static str> = Some("a string");
612 pub const parse_list
: Option
<&'
static str> = Some("a space-separated list of strings");
613 pub const parse_opt_list
: Option
<&'
static str> = Some("a space-separated list of strings");
614 pub const parse_uint
: Option
<&'
static str> = Some("a number");
615 pub const parse_passes
: Option
<&'
static str> =
616 Some("a space-separated list of passes, or `all`");
617 pub const parse_opt_uint
: Option
<&'
static str> =
619 pub const parse_panic_strategy
: Option
<&'
static str> =
620 Some("either `panic` or `abort`");
625 use super::{$struct_name, Passes, SomePasses, AllPasses, PanicStrategy}
;
628 pub fn $
opt(cg
: &mut $struct_name
, v
: Option
<&str>) -> bool
{
629 $
parse(&mut cg
.$opt
, v
)
633 fn parse_bool(slot
: &mut bool
, v
: Option
<&str>) -> bool
{
636 None
=> { *slot = true; true }
640 fn parse_opt_bool(slot
: &mut Option
<bool
>, v
: Option
<&str>) -> bool
{
644 "n" | "no" | "off" => {
647 "y" | "yes" | "on" => {
650 _
=> { return false; }
655 None
=> { *slot = Some(true); true }
659 fn parse_all_bool(slot
: &mut bool
, v
: Option
<&str>) -> bool
{
663 "n" | "no" | "off" => {
666 "y" | "yes" | "on" => {
669 _
=> { return false; }
674 None
=> { *slot = true; true }
678 fn parse_opt_string(slot
: &mut Option
<String
>, v
: Option
<&str>) -> bool
{
680 Some(s
) => { *slot = Some(s.to_string()); true }
,
685 fn parse_string(slot
: &mut String
, v
: Option
<&str>) -> bool
{
687 Some(s
) => { *slot = s.to_string(); true }
,
692 fn parse_list(slot
: &mut Vec
<String
>, v
: Option
<&str>)
696 for s
in s
.split_whitespace() {
697 slot
.push(s
.to_string());
705 fn parse_opt_list(slot
: &mut Option
<Vec
<String
>>, v
: Option
<&str>)
709 let v
= s
.split_whitespace().map(|s
| s
.to_string()).collect();
717 fn parse_uint(slot
: &mut usize, v
: Option
<&str>) -> bool
{
718 match v
.and_then(|s
| s
.parse().ok()) {
719 Some(i
) => { *slot = i; true }
,
724 fn parse_opt_uint(slot
: &mut Option
<usize>, v
: Option
<&str>) -> bool
{
726 Some(s
) => { *slot = s.parse().ok(); slot.is_some() }
727 None
=> { *slot = None; true }
731 fn parse_passes(slot
: &mut Passes
, v
: Option
<&str>) -> bool
{
738 let mut passes
= vec
!();
739 if parse_list(&mut passes
, v
) {
740 *slot
= SomePasses(passes
);
749 fn parse_panic_strategy(slot
: &mut PanicStrategy
, v
: Option
<&str>) -> bool
{
751 Some("unwind") => *slot
= PanicStrategy
::Unwind
,
752 Some("abort") => *slot
= PanicStrategy
::Abort
,
760 options
! {CodegenOptions
, CodegenSetter
, basic_codegen_options
,
761 build_codegen_options
, "C", "codegen",
762 CG_OPTIONS
, cg_type_desc
, cgsetters
,
763 ar
: Option
<String
> = (None
, parse_opt_string
, [UNTRACKED
],
764 "tool to assemble archives with"),
765 linker
: Option
<String
> = (None
, parse_opt_string
, [UNTRACKED
],
766 "system linker to link outputs with"),
767 link_args
: Option
<Vec
<String
>> = (None
, parse_opt_list
, [UNTRACKED
],
768 "extra arguments to pass to the linker (space separated)"),
769 link_dead_code
: bool
= (false, parse_bool
, [UNTRACKED
],
770 "don't let linker strip dead code (turning it on can be used for code coverage)"),
771 lto
: bool
= (false, parse_bool
, [TRACKED
],
772 "perform LLVM link-time optimizations"),
773 target_cpu
: Option
<String
> = (None
, parse_opt_string
, [TRACKED
],
774 "select target processor (rustc --print target-cpus for details)"),
775 target_feature
: String
= ("".to_string(), parse_string
, [TRACKED
],
776 "target specific attributes (rustc --print target-features for details)"),
777 passes
: Vec
<String
> = (Vec
::new(), parse_list
, [TRACKED
],
778 "a list of extra LLVM passes to run (space separated)"),
779 llvm_args
: Vec
<String
> = (Vec
::new(), parse_list
, [TRACKED
],
780 "a list of arguments to pass to llvm (space separated)"),
781 save_temps
: bool
= (false, parse_bool
, [UNTRACKED_WITH_WARNING(true,
782 "`-C save-temps` might not produce all requested temporary products \
783 when incremental compilation is enabled.")],
784 "save all temporary output files during compilation"),
785 rpath
: bool
= (false, parse_bool
, [UNTRACKED
],
786 "set rpath values in libs/exes"),
787 no_prepopulate_passes
: bool
= (false, parse_bool
, [TRACKED
],
788 "don't pre-populate the pass manager with a list of passes"),
789 no_vectorize_loops
: bool
= (false, parse_bool
, [TRACKED
],
790 "don't run the loop vectorization optimization passes"),
791 no_vectorize_slp
: bool
= (false, parse_bool
, [TRACKED
],
792 "don't run LLVM's SLP vectorization pass"),
793 soft_float
: bool
= (false, parse_bool
, [TRACKED
],
794 "generate software floating point library calls"),
795 prefer_dynamic
: bool
= (false, parse_bool
, [TRACKED
],
796 "prefer dynamic linking to static linking"),
797 no_integrated_as
: bool
= (false, parse_bool
, [TRACKED
],
798 "use an external assembler rather than LLVM's integrated one"),
799 no_redzone
: Option
<bool
> = (None
, parse_opt_bool
, [TRACKED
],
800 "disable the use of the redzone"),
801 relocation_model
: Option
<String
> = (None
, parse_opt_string
, [TRACKED
],
802 "choose the relocation model to use (rustc --print relocation-models for details)"),
803 code_model
: Option
<String
> = (None
, parse_opt_string
, [TRACKED
],
804 "choose the code model to use (rustc --print code-models for details)"),
805 metadata
: Vec
<String
> = (Vec
::new(), parse_list
, [TRACKED
],
806 "metadata to mangle symbol names with"),
807 extra_filename
: String
= ("".to_string(), parse_string
, [UNTRACKED
],
808 "extra data to put in each output filename"),
809 codegen_units
: usize = (1, parse_uint
, [UNTRACKED
],
810 "divide crate into N units to optimize in parallel"),
811 remark
: Passes
= (SomePasses(Vec
::new()), parse_passes
, [UNTRACKED
],
812 "print remarks for these optimization passes (space separated, or \"all\")"),
813 no_stack_check
: bool
= (false, parse_bool
, [UNTRACKED
],
814 "disable checks for stack exhaustion (a memory-safety hazard!)"),
815 debuginfo
: Option
<usize> = (None
, parse_opt_uint
, [TRACKED
],
816 "debug info emission level, 0 = no debug info, 1 = line tables only, \
817 2 = full debug info with variable and type information"),
818 opt_level
: Option
<String
> = (None
, parse_opt_string
, [TRACKED
],
819 "optimize with possible levels 0-3, s, or z"),
820 debug_assertions
: Option
<bool
> = (None
, parse_opt_bool
, [TRACKED
],
821 "explicitly enable the cfg(debug_assertions) directive"),
822 inline_threshold
: Option
<usize> = (None
, parse_opt_uint
, [TRACKED
],
823 "set the inlining threshold for"),
824 panic
: PanicStrategy
= (PanicStrategy
::Unwind
, parse_panic_strategy
,
825 [TRACKED
], "panic strategy to compile crate with"),
828 options
! {DebuggingOptions
, DebuggingSetter
, basic_debugging_options
,
829 build_debugging_options
, "Z", "debugging",
830 DB_OPTIONS
, db_type_desc
, dbsetters
,
831 verbose
: bool
= (false, parse_bool
, [UNTRACKED
],
832 "in general, enable more debug printouts"),
833 time_passes
: bool
= (false, parse_bool
, [UNTRACKED
],
834 "measure time of each rustc pass"),
835 count_llvm_insns
: bool
= (false, parse_bool
,
836 [UNTRACKED_WITH_WARNING(true,
837 "The output generated by `-Z count_llvm_insns` might not be reliable \
838 when used with incremental compilation")],
839 "count where LLVM instrs originate"),
840 time_llvm_passes
: bool
= (false, parse_bool
, [UNTRACKED_WITH_WARNING(true,
841 "The output of `-Z time-llvm-passes` will only reflect timings of \
842 re-translated modules when used with incremental compilation" )],
843 "measure time of each LLVM pass"),
844 input_stats
: bool
= (false, parse_bool
, [UNTRACKED
],
845 "gather statistics about the input"),
846 trans_stats
: bool
= (false, parse_bool
, [UNTRACKED_WITH_WARNING(true,
847 "The output of `-Z trans-stats` might not be accurate when incremental \
848 compilation is enabled")],
849 "gather trans statistics"),
850 asm_comments
: bool
= (false, parse_bool
, [TRACKED
],
851 "generate comments into the assembly (may change behavior)"),
852 no_verify
: bool
= (false, parse_bool
, [TRACKED
],
853 "skip LLVM verification"),
854 borrowck_stats
: bool
= (false, parse_bool
, [UNTRACKED
],
855 "gather borrowck statistics"),
856 no_landing_pads
: bool
= (false, parse_bool
, [TRACKED
],
857 "omit landing pads for unwinding"),
858 debug_llvm
: bool
= (false, parse_bool
, [UNTRACKED
],
859 "enable debug output from LLVM"),
860 meta_stats
: bool
= (false, parse_bool
, [UNTRACKED
],
861 "gather metadata statistics"),
862 print_link_args
: bool
= (false, parse_bool
, [UNTRACKED
],
863 "print the arguments passed to the linker"),
864 print_llvm_passes
: bool
= (false, parse_bool
, [UNTRACKED
],
865 "prints the llvm optimization passes being run"),
866 ast_json
: bool
= (false, parse_bool
, [UNTRACKED
],
867 "print the AST as JSON and halt"),
868 ast_json_noexpand
: bool
= (false, parse_bool
, [UNTRACKED
],
869 "print the pre-expansion AST as JSON and halt"),
870 ls
: bool
= (false, parse_bool
, [UNTRACKED
],
871 "list the symbols defined by a library crate"),
872 save_analysis
: bool
= (false, parse_bool
, [UNTRACKED
],
873 "write syntax and type analysis (in JSON format) information in addition to normal output"),
874 save_analysis_csv
: bool
= (false, parse_bool
, [UNTRACKED
],
875 "write syntax and type analysis (in CSV format) information in addition to normal output"),
876 print_move_fragments
: bool
= (false, parse_bool
, [UNTRACKED
],
877 "print out move-fragment data for every fn"),
878 flowgraph_print_loans
: bool
= (false, parse_bool
, [UNTRACKED
],
879 "include loan analysis data in --unpretty flowgraph output"),
880 flowgraph_print_moves
: bool
= (false, parse_bool
, [UNTRACKED
],
881 "include move analysis data in --unpretty flowgraph output"),
882 flowgraph_print_assigns
: bool
= (false, parse_bool
, [UNTRACKED
],
883 "include assignment analysis data in --unpretty flowgraph output"),
884 flowgraph_print_all
: bool
= (false, parse_bool
, [UNTRACKED
],
885 "include all dataflow analysis data in --unpretty flowgraph output"),
886 print_region_graph
: bool
= (false, parse_bool
, [UNTRACKED
],
887 "prints region inference graph. \
888 Use with RUST_REGION_GRAPH=help for more info"),
889 parse_only
: bool
= (false, parse_bool
, [UNTRACKED
],
890 "parse only; do not compile, assemble, or link"),
891 no_trans
: bool
= (false, parse_bool
, [TRACKED
],
892 "run all passes except translation; no output"),
893 treat_err_as_bug
: bool
= (false, parse_bool
, [TRACKED
],
894 "treat all errors that occur as bugs"),
895 continue_parse_after_error
: bool
= (false, parse_bool
, [TRACKED
],
896 "attempt to recover from parse errors (experimental)"),
897 incremental
: Option
<String
> = (None
, parse_opt_string
, [UNTRACKED
],
898 "enable incremental compilation (experimental)"),
899 incremental_info
: bool
= (false, parse_bool
, [UNTRACKED
],
900 "print high-level information about incremental reuse (or the lack thereof)"),
901 dump_dep_graph
: bool
= (false, parse_bool
, [UNTRACKED
],
902 "dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv)"),
903 query_dep_graph
: bool
= (false, parse_bool
, [UNTRACKED
],
904 "enable queries of the dependency graph for regression testing"),
905 no_analysis
: bool
= (false, parse_bool
, [UNTRACKED
],
906 "parse and expand the source, but run no analysis"),
907 extra_plugins
: Vec
<String
> = (Vec
::new(), parse_list
, [TRACKED
],
908 "load extra plugins"),
909 unstable_options
: bool
= (false, parse_bool
, [UNTRACKED
],
910 "adds unstable command line options to rustc interface"),
911 force_overflow_checks
: Option
<bool
> = (None
, parse_opt_bool
, [TRACKED
],
912 "force overflow checks on or off"),
913 force_dropflag_checks
: Option
<bool
> = (None
, parse_opt_bool
, [TRACKED
],
914 "force drop flag checks on or off"),
915 trace_macros
: bool
= (false, parse_bool
, [UNTRACKED
],
916 "for every macro invocation, print its name and arguments"),
917 enable_nonzeroing_move_hints
: bool
= (false, parse_bool
, [TRACKED
],
918 "force nonzeroing move optimization on"),
919 keep_hygiene_data
: bool
= (false, parse_bool
, [UNTRACKED
],
920 "don't clear the hygiene data after analysis"),
921 keep_ast
: bool
= (false, parse_bool
, [UNTRACKED
],
922 "keep the AST after lowering it to HIR"),
923 show_span
: Option
<String
> = (None
, parse_opt_string
, [TRACKED
],
924 "show spans for compiler debugging (expr|pat|ty)"),
925 print_trans_items
: Option
<String
> = (None
, parse_opt_string
, [UNTRACKED
],
926 "print the result of the translation item collection pass"),
927 mir_opt_level
: Option
<usize> = (None
, parse_opt_uint
, [TRACKED
],
928 "set the MIR optimization level (0-3)"),
929 dump_mir
: Option
<String
> = (None
, parse_opt_string
, [UNTRACKED
],
930 "dump MIR state at various points in translation"),
931 dump_mir_dir
: Option
<String
> = (None
, parse_opt_string
, [UNTRACKED
],
932 "the directory the MIR is dumped into"),
933 orbit
: bool
= (true, parse_all_bool
, [UNTRACKED
],
934 "get MIR where it belongs - everywhere; most importantly, in orbit"),
937 pub fn default_lib_output() -> CrateType
{
941 pub fn default_configuration(sess
: &Session
) -> ast
::CrateConfig
{
942 use syntax
::parse
::token
::intern_and_get_ident
as intern
;
944 let end
= &sess
.target
.target
.target_endian
;
945 let arch
= &sess
.target
.target
.arch
;
946 let wordsz
= &sess
.target
.target
.target_pointer_width
;
947 let os
= &sess
.target
.target
.target_os
;
948 let env
= &sess
.target
.target
.target_env
;
949 let vendor
= &sess
.target
.target
.target_vendor
;
950 let max_atomic_width
= sess
.target
.target
.options
.max_atomic_width
;
952 let fam
= if let Some(ref fam
) = sess
.target
.target
.options
.target_family
{
954 } else if sess
.target
.target
.options
.is_like_windows
{
955 InternedString
::new("windows")
957 InternedString
::new("unix")
960 let mk
= attr
::mk_name_value_item_str
;
961 let mut ret
= vec
![ // Target bindings.
962 mk(InternedString
::new("target_os"), intern(os
)),
963 mk(InternedString
::new("target_family"), fam
.clone()),
964 mk(InternedString
::new("target_arch"), intern(arch
)),
965 mk(InternedString
::new("target_endian"), intern(end
)),
966 mk(InternedString
::new("target_pointer_width"), intern(wordsz
)),
967 mk(InternedString
::new("target_env"), intern(env
)),
968 mk(InternedString
::new("target_vendor"), intern(vendor
)),
971 "windows" | "unix" => ret
.push(attr
::mk_word_item(fam
)),
974 if sess
.target
.target
.options
.has_elf_tls
{
975 ret
.push(attr
::mk_word_item(InternedString
::new("target_thread_local")));
977 for &i
in &[8, 16, 32, 64, 128] {
978 if i
<= max_atomic_width
{
979 let s
= i
.to_string();
980 ret
.push(mk(InternedString
::new("target_has_atomic"), intern(&s
)));
982 ret
.push(mk(InternedString
::new("target_has_atomic"), intern("ptr")));
986 if sess
.opts
.debug_assertions
{
987 ret
.push(attr
::mk_word_item(InternedString
::new("debug_assertions")));
992 pub fn append_configuration(cfg
: &mut ast
::CrateConfig
,
993 name
: InternedString
) {
994 if !cfg
.iter().any(|mi
| mi
.name() == name
) {
995 cfg
.push(attr
::mk_word_item(name
))
999 pub fn build_configuration(sess
: &Session
,
1000 mut user_cfg
: ast
::CrateConfig
)
1001 -> ast
::CrateConfig
{
1002 // Combine the configuration requested by the session (command line) with
1003 // some default and generated configuration items
1004 let default_cfg
= default_configuration(sess
);
1005 // If the user wants a test runner, then add the test cfg
1007 append_configuration(&mut user_cfg
, InternedString
::new("test"))
1009 let mut v
= user_cfg
.into_iter().collect
::<Vec
<_
>>();
1010 v
.extend_from_slice(&default_cfg
[..]);
1014 pub fn build_target_config(opts
: &Options
, sp
: &Handler
) -> Config
{
1015 let target
= match Target
::search(&opts
.target_triple
) {
1018 sp
.struct_fatal(&format
!("Error loading target specification: {}", e
))
1019 .help("Use `--print target-list` for a list of built-in targets")
1025 let (int_type
, uint_type
) = match &target
.target_pointer_width
[..] {
1026 "16" => (ast
::IntTy
::I16
, ast
::UintTy
::U16
),
1027 "32" => (ast
::IntTy
::I32
, ast
::UintTy
::U32
),
1028 "64" => (ast
::IntTy
::I64
, ast
::UintTy
::U64
),
1029 w
=> panic
!(sp
.fatal(&format
!("target specification was invalid: \
1030 unrecognized target-pointer-width {}", w
))),
1036 uint_type
: uint_type
,
1040 #[derive(Copy, Clone, PartialEq, Eq, Debug)]
1041 pub enum OptionStability
{
1044 // FIXME: historically there were some options which were either `-Z` or
1045 // required the `-Z unstable-options` flag, which were all intended
1046 // to be unstable. Unfortunately we didn't actually gate usage of
1047 // these options on the stable compiler, so we still allow them there
1048 // today. There are some warnings printed out about this in the
1050 UnstableButNotReally
,
1055 #[derive(Clone, PartialEq, Eq)]
1056 pub struct RustcOptGroup
{
1057 pub opt_group
: getopts
::OptGroup
,
1058 pub stability
: OptionStability
,
1061 impl RustcOptGroup
{
1062 pub fn is_stable(&self) -> bool
{
1063 self.stability
== OptionStability
::Stable
1066 pub fn stable(g
: getopts
::OptGroup
) -> RustcOptGroup
{
1067 RustcOptGroup { opt_group: g, stability: OptionStability::Stable }
1070 #[allow(dead_code)] // currently we have no "truly unstable" options
1071 pub fn unstable(g
: getopts
::OptGroup
) -> RustcOptGroup
{
1072 RustcOptGroup { opt_group: g, stability: OptionStability::Unstable }
1075 fn unstable_bnr(g
: getopts
::OptGroup
) -> RustcOptGroup
{
1078 stability
: OptionStability
::UnstableButNotReally
,
1083 // The `opt` local module holds wrappers around the `getopts` API that
1084 // adds extra rustc-specific metadata to each option; such metadata
1085 // is exposed by . The public
1086 // functions below ending with `_u` are the functions that return
1087 // *unstable* options, i.e. options that are only enabled when the
1088 // user also passes the `-Z unstable-options` debugging flag.
1090 // The `fn opt_u` etc below are written so that we can use them
1091 // in the future; do not warn about them not being used right now.
1092 #![allow(dead_code)]
1095 use super::RustcOptGroup
;
1097 pub type R
= RustcOptGroup
;
1098 pub type S
<'a
> = &'a
str;
1100 fn stable(g
: getopts
::OptGroup
) -> R { RustcOptGroup::stable(g) }
1101 fn unstable(g
: getopts
::OptGroup
) -> R { RustcOptGroup::unstable(g) }
1102 fn unstable_bnr(g
: getopts
::OptGroup
) -> R { RustcOptGroup::unstable_bnr(g) }
1104 pub fn opt_s(a
: S
, b
: S
, c
: S
, d
: S
) -> R
{
1105 stable(getopts
::optopt(a
, b
, c
, d
))
1107 pub fn multi_s(a
: S
, b
: S
, c
: S
, d
: S
) -> R
{
1108 stable(getopts
::optmulti(a
, b
, c
, d
))
1110 pub fn flag_s(a
: S
, b
: S
, c
: S
) -> R
{
1111 stable(getopts
::optflag(a
, b
, c
))
1113 pub fn flagopt_s(a
: S
, b
: S
, c
: S
, d
: S
) -> R
{
1114 stable(getopts
::optflagopt(a
, b
, c
, d
))
1116 pub fn flagmulti_s(a
: S
, b
: S
, c
: S
) -> R
{
1117 stable(getopts
::optflagmulti(a
, b
, c
))
1120 pub fn opt(a
: S
, b
: S
, c
: S
, d
: S
) -> R
{
1121 unstable(getopts
::optopt(a
, b
, c
, d
))
1123 pub fn multi(a
: S
, b
: S
, c
: S
, d
: S
) -> R
{
1124 unstable(getopts
::optmulti(a
, b
, c
, d
))
1126 pub fn flag(a
: S
, b
: S
, c
: S
) -> R
{
1127 unstable(getopts
::optflag(a
, b
, c
))
1129 pub fn flagopt(a
: S
, b
: S
, c
: S
, d
: S
) -> R
{
1130 unstable(getopts
::optflagopt(a
, b
, c
, d
))
1132 pub fn flagmulti(a
: S
, b
: S
, c
: S
) -> R
{
1133 unstable(getopts
::optflagmulti(a
, b
, c
))
1136 // Do not use these functions for any new options added to the compiler, all
1137 // new options should use the `*_u` variants above to be truly unstable.
1138 pub fn opt_ubnr(a
: S
, b
: S
, c
: S
, d
: S
) -> R
{
1139 unstable_bnr(getopts
::optopt(a
, b
, c
, d
))
1141 pub fn multi_ubnr(a
: S
, b
: S
, c
: S
, d
: S
) -> R
{
1142 unstable_bnr(getopts
::optmulti(a
, b
, c
, d
))
1144 pub fn flag_ubnr(a
: S
, b
: S
, c
: S
) -> R
{
1145 unstable_bnr(getopts
::optflag(a
, b
, c
))
1147 pub fn flagopt_ubnr(a
: S
, b
: S
, c
: S
, d
: S
) -> R
{
1148 unstable_bnr(getopts
::optflagopt(a
, b
, c
, d
))
1150 pub fn flagmulti_ubnr(a
: S
, b
: S
, c
: S
) -> R
{
1151 unstable_bnr(getopts
::optflagmulti(a
, b
, c
))
1155 /// Returns the "short" subset of the rustc command line options,
1156 /// including metadata for each option, such as whether the option is
1157 /// part of the stable long-term interface for rustc.
1158 pub fn rustc_short_optgroups() -> Vec
<RustcOptGroup
> {
1160 opt
::flag_s("h", "help", "Display this message"),
1161 opt
::multi_s("", "cfg", "Configure the compilation environment", "SPEC"),
1162 opt
::multi_s("L", "", "Add a directory to the library search path. The
1163 optional KIND can be one of dependency, crate, native,
1164 framework or all (the default).", "[KIND=]PATH"),
1165 opt
::multi_s("l", "", "Link the generated crate(s) to the specified native
1166 library NAME. The optional KIND can be one of
1167 static, dylib, or framework. If omitted, dylib is
1168 assumed.", "[KIND=]NAME"),
1169 opt
::multi_s("", "crate-type", "Comma separated list of types of crates
1170 for the compiler to emit",
1171 "[bin|lib|rlib|dylib|cdylib|staticlib]"),
1172 opt
::opt_s("", "crate-name", "Specify the name of the crate being built",
1174 opt
::multi_s("", "emit", "Comma separated list of types of output for \
1175 the compiler to emit",
1176 "[asm|llvm-bc|llvm-ir|obj|link|dep-info]"),
1177 opt
::multi_s("", "print", "Comma separated list of compiler information to \
1179 "[crate-name|file-names|sysroot|cfg|target-list|target-cpus|\
1180 target-features|relocation-models|code-models]"),
1181 opt
::flagmulti_s("g", "", "Equivalent to -C debuginfo=2"),
1182 opt
::flagmulti_s("O", "", "Equivalent to -C opt-level=2"),
1183 opt
::opt_s("o", "", "Write output to <filename>", "FILENAME"),
1184 opt
::opt_s("", "out-dir", "Write output to compiler-chosen filename \
1186 opt
::opt_s("", "explain", "Provide a detailed explanation of an error \
1188 opt
::flag_s("", "test", "Build a test harness"),
1189 opt
::opt_s("", "target", "Target triple for which the code is compiled", "TARGET"),
1190 opt
::multi_s("W", "warn", "Set lint warnings", "OPT"),
1191 opt
::multi_s("A", "allow", "Set lint allowed", "OPT"),
1192 opt
::multi_s("D", "deny", "Set lint denied", "OPT"),
1193 opt
::multi_s("F", "forbid", "Set lint forbidden", "OPT"),
1194 opt
::multi_s("", "cap-lints", "Set the most restrictive lint level. \
1195 More restrictive lints are capped at this \
1197 opt
::multi_s("C", "codegen", "Set a codegen option", "OPT[=VALUE]"),
1198 opt
::flag_s("V", "version", "Print version info and exit"),
1199 opt
::flag_s("v", "verbose", "Use verbose output"),
1203 /// Returns all rustc command line options, including metadata for
1204 /// each option, such as whether the option is part of the stable
1205 /// long-term interface for rustc.
1206 pub fn rustc_optgroups() -> Vec
<RustcOptGroup
> {
1207 let mut opts
= rustc_short_optgroups();
1208 opts
.extend_from_slice(&[
1209 opt
::multi_s("", "extern", "Specify where an external rust library is located",
1211 opt
::opt_s("", "sysroot", "Override the system root", "PATH"),
1212 opt
::multi_ubnr("Z", "", "Set internal debugging options", "FLAG"),
1213 opt
::opt_s("", "error-format",
1214 "How errors and other messages are produced",
1216 opt
::opt_s("", "color", "Configure coloring of output:
1217 auto = colorize, if output goes to a tty (default);
1218 always = always colorize output;
1219 never = never colorize output", "auto|always|never"),
1221 opt
::flagopt_ubnr("", "pretty",
1222 "Pretty-print the input instead of compiling;
1223 valid types are: `normal` (un-annotated source),
1224 `expanded` (crates expanded), or
1225 `expanded,identified` (fully parenthesized, AST nodes with IDs).",
1227 opt
::flagopt_ubnr("", "unpretty",
1228 "Present the input source, unstable (and less-pretty) variants;
1229 valid types are any of the types for `--pretty`, as well as:
1230 `flowgraph=<nodeid>` (graphviz formatted flowgraph for node),
1231 `everybody_loops` (all function bodies replaced with `loop {}`),
1232 `hir` (the HIR), `hir,identified`, or
1233 `hir,typed` (HIR with types for each node).",
1236 // new options here should **not** use the `_ubnr` functions, all new
1237 // unstable options should use the short variants to indicate that they
1238 // are truly unstable. All `_ubnr` flags are just that way because they
1239 // were so historically.
1241 // You may also wish to keep this comment at the bottom of this list to
1242 // ensure that others see it.
1247 // Convert strings provided as --cfg [cfgspec] into a crate_cfg
1248 pub fn parse_cfgspecs(cfgspecs
: Vec
<String
> ) -> ast
::CrateConfig
{
1249 cfgspecs
.into_iter().map(|s
| {
1250 let sess
= parse
::ParseSess
::new();
1251 let mut parser
= parse
::new_parser_from_source_str(&sess
,
1253 "cfgspec".to_string(),
1255 let meta_item
= panictry
!(parser
.parse_meta_item());
1257 if !parser
.reader
.is_eof() {
1258 early_error(ErrorOutputType
::default(), &format
!("invalid --cfg argument: {}",
1263 }).collect
::<ast
::CrateConfig
>()
1266 pub fn build_session_options_and_crate_config(matches
: &getopts
::Matches
)
1267 -> (Options
, ast
::CrateConfig
) {
1268 let color
= match matches
.opt_str("color").as_ref().map(|s
| &s
[..]) {
1269 Some("auto") => ColorConfig
::Auto
,
1270 Some("always") => ColorConfig
::Always
,
1271 Some("never") => ColorConfig
::Never
,
1273 None
=> ColorConfig
::Auto
,
1276 early_error(ErrorOutputType
::default(), &format
!("argument for --color must be auto, \
1277 always or never (instead was `{}`)",
1282 // We need the opts_present check because the driver will send us Matches
1283 // with only stable options if no unstable options are used. Since error-format
1284 // is unstable, it will not be present. We have to use opts_present not
1285 // opt_present because the latter will panic.
1286 let error_format
= if matches
.opts_present(&["error-format".to_owned()]) {
1287 match matches
.opt_str("error-format").as_ref().map(|s
| &s
[..]) {
1288 Some("human") => ErrorOutputType
::HumanReadable(color
),
1289 Some("json") => ErrorOutputType
::Json
,
1291 None
=> ErrorOutputType
::HumanReadable(color
),
1294 early_error(ErrorOutputType
::HumanReadable(color
),
1295 &format
!("argument for --error-format must be human or json (instead \
1301 ErrorOutputType
::HumanReadable(color
)
1304 let unparsed_crate_types
= matches
.opt_strs("crate-type");
1305 let crate_types
= parse_crate_types_from_list(unparsed_crate_types
)
1306 .unwrap_or_else(|e
| early_error(error_format
, &e
[..]));
1308 let mut lint_opts
= vec
!();
1309 let mut describe_lints
= false;
1311 for &level
in &[lint
::Allow
, lint
::Warn
, lint
::Deny
, lint
::Forbid
] {
1312 for lint_name
in matches
.opt_strs(level
.as_str()) {
1313 if lint_name
== "help" {
1314 describe_lints
= true;
1316 lint_opts
.push((lint_name
.replace("-", "_"), level
));
1321 let lint_cap
= matches
.opt_str("cap-lints").map(|cap
| {
1322 lint
::Level
::from_str(&cap
).unwrap_or_else(|| {
1323 early_error(error_format
, &format
!("unknown lint level: `{}`", cap
))
1327 let mut debugging_opts
= build_debugging_options(matches
, error_format
);
1329 // Incremental compilation only works reliably when translation is done via
1330 // MIR, so let's enable -Z orbit if necessary (see #34973).
1331 if debugging_opts
.incremental
.is_some() && !debugging_opts
.orbit
{
1332 early_warn(error_format
, "Automatically enabling `-Z orbit` because \
1333 `-Z incremental` was specified");
1334 debugging_opts
.orbit
= true;
1337 let mir_opt_level
= debugging_opts
.mir_opt_level
.unwrap_or(1);
1339 let mut output_types
= BTreeMap
::new();
1340 if !debugging_opts
.parse_only
{
1341 for list
in matches
.opt_strs("emit") {
1342 for output_type
in list
.split('
,'
) {
1343 let mut parts
= output_type
.splitn(2, '
='
);
1344 let output_type
= match parts
.next().unwrap() {
1345 "asm" => OutputType
::Assembly
,
1346 "llvm-ir" => OutputType
::LlvmAssembly
,
1347 "llvm-bc" => OutputType
::Bitcode
,
1348 "obj" => OutputType
::Object
,
1349 "link" => OutputType
::Exe
,
1350 "dep-info" => OutputType
::DepInfo
,
1352 early_error(error_format
, &format
!("unknown emission type: `{}`",
1356 let path
= parts
.next().map(PathBuf
::from
);
1357 output_types
.insert(output_type
, path
);
1361 if output_types
.is_empty() {
1362 output_types
.insert(OutputType
::Exe
, None
);
1365 let mut cg
= build_codegen_options(matches
, error_format
);
1367 // Issue #30063: if user requests llvm-related output to one
1368 // particular path, disable codegen-units.
1369 if matches
.opt_present("o") && cg
.codegen_units
!= 1 {
1370 let incompatible
: Vec
<_
> = output_types
.iter()
1371 .map(|ot_path
| ot_path
.0)
1373 !ot
.is_compatible_with_codegen_units_and_single_output_file()
1375 if !incompatible
.is_empty() {
1376 for ot
in &incompatible
{
1377 early_warn(error_format
, &format
!("--emit={} with -o incompatible with \
1378 -C codegen-units=N for N > 1",
1381 early_warn(error_format
, "resetting to default -C codegen-units=1");
1382 cg
.codegen_units
= 1;
1386 if cg
.codegen_units
< 1 {
1387 early_error(error_format
, "Value for codegen units must be a positive nonzero integer");
1390 let mut prints
= Vec
::<PrintRequest
>::new();
1391 if cg
.target_cpu
.as_ref().map_or(false, |s
| s
== "help") {
1392 prints
.push(PrintRequest
::TargetCPUs
);
1393 cg
.target_cpu
= None
;
1395 if cg
.target_feature
== "help" {
1396 prints
.push(PrintRequest
::TargetFeatures
);
1397 cg
.target_feature
= "".to_string();
1399 if cg
.relocation_model
.as_ref().map_or(false, |s
| s
== "help") {
1400 prints
.push(PrintRequest
::RelocationModels
);
1401 cg
.relocation_model
= None
;
1403 if cg
.code_model
.as_ref().map_or(false, |s
| s
== "help") {
1404 prints
.push(PrintRequest
::CodeModels
);
1405 cg
.code_model
= None
;
1410 let sysroot_opt
= matches
.opt_str("sysroot").map(|m
| PathBuf
::from(&m
));
1411 let target
= matches
.opt_str("target").unwrap_or(
1412 host_triple().to_string());
1414 if matches
.opt_present("O") {
1415 if cg
.opt_level
.is_some() {
1416 early_error(error_format
, "-O and -C opt-level both provided");
1420 match (cg
.opt_level
.as_ref().map(String
::as_ref
),
1421 nightly_options
::is_nightly_build()) {
1422 (None
, _
) => OptLevel
::No
,
1423 (Some("0"), _
) => OptLevel
::No
,
1424 (Some("1"), _
) => OptLevel
::Less
,
1425 (Some("2"), _
) => OptLevel
::Default
,
1426 (Some("3"), _
) => OptLevel
::Aggressive
,
1427 (Some("s"), true) => OptLevel
::Size
,
1428 (Some("z"), true) => OptLevel
::SizeMin
,
1429 (Some("s"), false) | (Some("z"), false) => {
1430 early_error(error_format
, &format
!("the optimizations s or z are only \
1431 accepted on the nightly compiler"));
1434 early_error(error_format
, &format
!("optimization level needs to be \
1435 between 0-3 (instead was `{}`)",
1441 let debug_assertions
= cg
.debug_assertions
.unwrap_or(opt_level
== OptLevel
::No
);
1442 let debuginfo
= if matches
.opt_present("g") {
1443 if cg
.debuginfo
.is_some() {
1444 early_error(error_format
, "-g and -C debuginfo both provided");
1448 match cg
.debuginfo
{
1449 None
| Some(0) => NoDebugInfo
,
1450 Some(1) => LimitedDebugInfo
,
1451 Some(2) => FullDebugInfo
,
1453 early_error(error_format
, &format
!("debug info level needs to be between \
1454 0-2 (instead was `{}`)",
1460 let mut search_paths
= SearchPaths
::new();
1461 for s
in &matches
.opt_strs("L") {
1462 search_paths
.add_path(&s
[..], error_format
);
1465 let libs
= matches
.opt_strs("l").into_iter().map(|s
| {
1466 let mut parts
= s
.splitn(2, '
='
);
1467 let kind
= parts
.next().unwrap();
1468 let (name
, kind
) = match (parts
.next(), kind
) {
1470 (Some(name
), "dylib") => (name
, cstore
::NativeUnknown
),
1471 (Some(name
), "framework") => (name
, cstore
::NativeFramework
),
1472 (Some(name
), "static") => (name
, cstore
::NativeStatic
),
1474 early_error(error_format
, &format
!("unknown library kind `{}`, expected \
1475 one of dylib, framework, or static",
1479 (name
.to_string(), kind
)
1482 let cfg
= parse_cfgspecs(matches
.opt_strs("cfg"));
1483 let test
= matches
.opt_present("test");
1485 prints
.extend(matches
.opt_strs("print").into_iter().map(|s
| {
1487 "crate-name" => PrintRequest
::CrateName
,
1488 "file-names" => PrintRequest
::FileNames
,
1489 "sysroot" => PrintRequest
::Sysroot
,
1490 "cfg" => PrintRequest
::Cfg
,
1491 "target-list" => PrintRequest
::TargetList
,
1492 "target-cpus" => PrintRequest
::TargetCPUs
,
1493 "target-features" => PrintRequest
::TargetFeatures
,
1494 "relocation-models" => PrintRequest
::RelocationModels
,
1495 "code-models" => PrintRequest
::CodeModels
,
1497 early_error(error_format
, &format
!("unknown print request `{}`", req
))
1502 if !cg
.remark
.is_empty() && debuginfo
== NoDebugInfo
{
1503 early_warn(error_format
, "-C remark will not show source locations without \
1507 let mut externs
= BTreeMap
::new();
1508 for arg
in &matches
.opt_strs("extern") {
1509 let mut parts
= arg
.splitn(2, '
='
);
1510 let name
= match parts
.next() {
1512 None
=> early_error(error_format
, "--extern value must not be empty"),
1514 let location
= match parts
.next() {
1516 None
=> early_error(error_format
, "--extern value must be of the format `foo=bar`"),
1519 externs
.entry(name
.to_string())
1520 .or_insert_with(BTreeSet
::new
)
1521 .insert(location
.to_string());
1524 let crate_name
= matches
.opt_str("crate-name");
1526 let incremental
= debugging_opts
.incremental
.as_ref().map(|m
| PathBuf
::from(m
));
1529 crate_types
: crate_types
,
1530 optimize
: opt_level
,
1531 debuginfo
: debuginfo
,
1532 lint_opts
: lint_opts
,
1534 describe_lints
: describe_lints
,
1535 output_types
: OutputTypes(output_types
),
1536 search_paths
: search_paths
,
1537 maybe_sysroot
: sysroot_opt
,
1538 target_triple
: target
,
1540 mir_opt_level
: mir_opt_level
,
1541 incremental
: incremental
,
1542 debugging_opts
: debugging_opts
,
1545 error_format
: error_format
,
1546 externs
: Externs(externs
),
1547 crate_name
: crate_name
,
1550 unstable_features
: get_unstable_features_setting(),
1551 debug_assertions
: debug_assertions
,
1556 pub fn get_unstable_features_setting() -> UnstableFeatures
{
1557 // Whether this is a feature-staged build, i.e. on the beta or stable channel
1558 let disable_unstable_features
= option_env
!("CFG_DISABLE_UNSTABLE_FEATURES").is_some();
1559 // The secret key needed to get through the rustc build itself by
1560 // subverting the unstable features lints
1561 let bootstrap_secret_key
= option_env
!("CFG_BOOTSTRAP_KEY");
1562 // The matching key to the above, only known by the build system
1563 let bootstrap_provided_key
= env
::var("RUSTC_BOOTSTRAP_KEY").ok();
1564 match (disable_unstable_features
, bootstrap_secret_key
, bootstrap_provided_key
) {
1565 (_
, Some(ref s
), Some(ref p
)) if s
== p
=> UnstableFeatures
::Cheat
,
1566 (true, _
, _
) => UnstableFeatures
::Disallow
,
1567 (false, _
, _
) => UnstableFeatures
::Allow
1571 pub fn parse_crate_types_from_list(list_list
: Vec
<String
>) -> Result
<Vec
<CrateType
>, String
> {
1572 let mut crate_types
: Vec
<CrateType
> = Vec
::new();
1573 for unparsed_crate_type
in &list_list
{
1574 for part
in unparsed_crate_type
.split('
,'
) {
1575 let new_part
= match part
{
1576 "lib" => default_lib_output(),
1577 "rlib" => CrateTypeRlib
,
1578 "staticlib" => CrateTypeStaticlib
,
1579 "dylib" => CrateTypeDylib
,
1580 "cdylib" => CrateTypeCdylib
,
1581 "bin" => CrateTypeExecutable
,
1583 return Err(format
!("unknown crate type: `{}`",
1587 if !crate_types
.contains(&new_part
) {
1588 crate_types
.push(new_part
)
1593 return Ok(crate_types
);
1596 pub mod nightly_options
{
1598 use syntax
::feature_gate
::UnstableFeatures
;
1599 use super::{ErrorOutputType, OptionStability, RustcOptGroup, get_unstable_features_setting}
;
1600 use session
::{early_error, early_warn}
;
1602 pub fn is_unstable_enabled(matches
: &getopts
::Matches
) -> bool
{
1603 is_nightly_build() && matches
.opt_strs("Z").iter().any(|x
| *x
== "unstable-options")
1606 pub fn is_nightly_build() -> bool
{
1607 match get_unstable_features_setting() {
1608 UnstableFeatures
::Allow
| UnstableFeatures
::Cheat
=> true,
1613 pub fn check_nightly_options(matches
: &getopts
::Matches
, flags
: &[RustcOptGroup
]) {
1614 let has_z_unstable_option
= matches
.opt_strs("Z").iter().any(|x
| *x
== "unstable-options");
1615 let really_allows_unstable_options
= match get_unstable_features_setting() {
1616 UnstableFeatures
::Disallow
=> false,
1620 for opt
in flags
.iter() {
1621 if opt
.stability
== OptionStability
::Stable
{
1624 let opt_name
= if opt
.opt_group
.long_name
.is_empty() {
1625 &opt
.opt_group
.short_name
1627 &opt
.opt_group
.long_name
1629 if !matches
.opt_present(opt_name
) {
1632 if opt_name
!= "Z" && !has_z_unstable_option
{
1633 early_error(ErrorOutputType
::default(),
1634 &format
!("the `-Z unstable-options` flag must also be passed to enable \
1638 if really_allows_unstable_options
{
1641 match opt
.stability
{
1642 OptionStability
::Unstable
=> {
1643 let msg
= format
!("the option `{}` is only accepted on the \
1644 nightly compiler", opt_name
);
1645 early_error(ErrorOutputType
::default(), &msg
);
1647 OptionStability
::UnstableButNotReally
=> {
1648 let msg
= format
!("the option `{}` is unstable and should \
1649 only be used on the nightly compiler, but \
1650 it is currently accepted for backwards \
1651 compatibility; this will soon change, \
1652 see issue #31847 for more details",
1654 early_warn(ErrorOutputType
::default(), &msg
);
1656 OptionStability
::Stable
=> {}
1662 impl fmt
::Display
for CrateType
{
1663 fn fmt(&self, f
: &mut fmt
::Formatter
) -> fmt
::Result
{
1665 CrateTypeExecutable
=> "bin".fmt(f
),
1666 CrateTypeDylib
=> "dylib".fmt(f
),
1667 CrateTypeRlib
=> "rlib".fmt(f
),
1668 CrateTypeStaticlib
=> "staticlib".fmt(f
),
1669 CrateTypeCdylib
=> "cdylib".fmt(f
),
1674 /// Commandline arguments passed to the compiler have to be incorporated with
1675 /// the dependency tracking system for incremental compilation. This module
1676 /// provides some utilities to make this more convenient.
1678 /// The values of all commandline arguments that are relevant for dependency
1679 /// tracking are hashed into a single value that determines whether the
1680 /// incremental compilation cache can be re-used or not. This hashing is done
1681 /// via the DepTrackingHash trait defined below, since the standard Hash
1682 /// implementation might not be suitable (e.g. arguments are stored in a Vec,
1683 /// the hash of which is order dependent, but we might not want the order of
1684 /// arguments to make a difference for the hash).
1686 /// However, since the value provided by Hash::hash often *is* suitable,
1687 /// especially for primitive types, there is the
1688 /// impl_dep_tracking_hash_via_hash!() macro that allows to simply reuse the
1689 /// Hash implementation for DepTrackingHash. It's important though that
1690 /// we have an opt-in scheme here, so one is hopefully forced to think about
1691 /// how the hash should be calculated when adding a new commandline argument.
1695 use session
::search_paths
::{PathKind, SearchPaths}
;
1696 use std
::collections
::BTreeMap
;
1697 use std
::hash
::{Hash, SipHasher}
;
1698 use std
::path
::PathBuf
;
1699 use super::{Passes
, PanicStrategy
, CrateType
, OptLevel
, DebugInfoLevel
,
1700 OutputTypes
, Externs
, ErrorOutputType
};
1701 use syntax
::feature_gate
::UnstableFeatures
;
1703 pub trait DepTrackingHash
{
1704 fn hash(&self, &mut SipHasher
, ErrorOutputType
);
1707 macro_rules
! impl_dep_tracking_hash_via_hash
{
1709 impl DepTrackingHash
for $t
{
1710 fn hash(&self, hasher
: &mut SipHasher
, _
: ErrorOutputType
) {
1711 Hash
::hash(self, hasher
);
1717 macro_rules
! impl_dep_tracking_hash_for_sortable_vec_of
{
1719 impl DepTrackingHash
for Vec
<$t
> {
1720 fn hash(&self, hasher
: &mut SipHasher
, error_format
: ErrorOutputType
) {
1721 let mut elems
: Vec
<&$t
> = self.iter().collect();
1723 Hash
::hash(&elems
.len(), hasher
);
1724 for (index
, elem
) in elems
.iter().enumerate() {
1725 Hash
::hash(&index
, hasher
);
1726 DepTrackingHash
::hash(*elem
, hasher
, error_format
);
1733 impl_dep_tracking_hash_via_hash
!(bool
);
1734 impl_dep_tracking_hash_via_hash
!(usize);
1735 impl_dep_tracking_hash_via_hash
!(String
);
1736 impl_dep_tracking_hash_via_hash
!(lint
::Level
);
1737 impl_dep_tracking_hash_via_hash
!(Option
<bool
>);
1738 impl_dep_tracking_hash_via_hash
!(Option
<usize>);
1739 impl_dep_tracking_hash_via_hash
!(Option
<String
>);
1740 impl_dep_tracking_hash_via_hash
!(Option
<lint
::Level
>);
1741 impl_dep_tracking_hash_via_hash
!(Option
<PathBuf
>);
1742 impl_dep_tracking_hash_via_hash
!(CrateType
);
1743 impl_dep_tracking_hash_via_hash
!(PanicStrategy
);
1744 impl_dep_tracking_hash_via_hash
!(Passes
);
1745 impl_dep_tracking_hash_via_hash
!(OptLevel
);
1746 impl_dep_tracking_hash_via_hash
!(DebugInfoLevel
);
1747 impl_dep_tracking_hash_via_hash
!(UnstableFeatures
);
1748 impl_dep_tracking_hash_via_hash
!(Externs
);
1749 impl_dep_tracking_hash_via_hash
!(OutputTypes
);
1750 impl_dep_tracking_hash_via_hash
!(cstore
::NativeLibraryKind
);
1752 impl_dep_tracking_hash_for_sortable_vec_of
!(String
);
1753 impl_dep_tracking_hash_for_sortable_vec_of
!(CrateType
);
1754 impl_dep_tracking_hash_for_sortable_vec_of
!((String
, lint
::Level
));
1755 impl_dep_tracking_hash_for_sortable_vec_of
!((String
, cstore
::NativeLibraryKind
));
1757 impl DepTrackingHash
for SearchPaths
{
1758 fn hash(&self, hasher
: &mut SipHasher
, _
: ErrorOutputType
) {
1759 let mut elems
: Vec
<_
> = self
1760 .iter(PathKind
::All
)
1763 Hash
::hash(&elems
, hasher
);
1767 impl<T1
, T2
> DepTrackingHash
for (T1
, T2
)
1768 where T1
: DepTrackingHash
,
1771 fn hash(&self, hasher
: &mut SipHasher
, error_format
: ErrorOutputType
) {
1772 Hash
::hash(&0, hasher
);
1773 DepTrackingHash
::hash(&self.0, hasher
, error_format
);
1774 Hash
::hash(&1, hasher
);
1775 DepTrackingHash
::hash(&self.1, hasher
, error_format
);
1779 // This is a stable hash because BTreeMap is a sorted container
1780 pub fn stable_hash(sub_hashes
: BTreeMap
<&'
static str, &DepTrackingHash
>,
1781 hasher
: &mut SipHasher
,
1782 error_format
: ErrorOutputType
) {
1783 for (key
, sub_hash
) in sub_hashes
{
1784 // Using Hash::hash() instead of DepTrackingHash::hash() is fine for
1785 // the keys, as they are just plain strings
1786 Hash
::hash(&key
.len(), hasher
);
1787 Hash
::hash(key
, hasher
);
1788 sub_hash
.hash(hasher
, error_format
);
1795 use dep_graph
::DepGraph
;
1797 use getopts
::{getopts, OptGroup}
;
1799 use middle
::cstore
::{self, DummyCrateStore}
;
1800 use session
::config
::{build_configuration, build_session_options_and_crate_config}
;
1801 use session
::build_session
;
1802 use std
::collections
::{BTreeMap, BTreeSet}
;
1803 use std
::iter
::FromIterator
;
1804 use std
::path
::PathBuf
;
1806 use super::{OutputType, OutputTypes, Externs, PanicStrategy}
;
1808 use syntax
::attr
::AttrMetaMethods
;
1810 fn optgroups() -> Vec
<OptGroup
> {
1811 super::rustc_optgroups().into_iter()
1812 .map(|a
| a
.opt_group
)
1816 fn mk_map
<K
: Ord
, V
>(entries
: Vec
<(K
, V
)>) -> BTreeMap
<K
, V
> {
1817 BTreeMap
::from_iter(entries
.into_iter())
1820 fn mk_set
<V
: Ord
>(entries
: Vec
<V
>) -> BTreeSet
<V
> {
1821 BTreeSet
::from_iter(entries
.into_iter())
1824 // When the user supplies --test we should implicitly supply --cfg test
1826 fn test_switch_implies_cfg_test() {
1827 let dep_graph
= DepGraph
::new(false);
1829 &match getopts(&["--test".to_string()], &optgroups()) {
1831 Err(f
) => panic
!("test_switch_implies_cfg_test: {}", f
)
1833 let registry
= errors
::registry
::Registry
::new(&[]);
1834 let (sessopts
, cfg
) = build_session_options_and_crate_config(matches
);
1835 let sess
= build_session(sessopts
, &dep_graph
, None
, registry
, Rc
::new(DummyCrateStore
));
1836 let cfg
= build_configuration(&sess
, cfg
);
1837 assert
!((attr
::contains_name(&cfg
[..], "test")));
1840 // When the user supplies --test and --cfg test, don't implicitly add
1841 // another --cfg test
1843 fn test_switch_implies_cfg_test_unless_cfg_test() {
1844 let dep_graph
= DepGraph
::new(false);
1846 &match getopts(&["--test".to_string(), "--cfg=test".to_string()],
1850 panic
!("test_switch_implies_cfg_test_unless_cfg_test: {}", f
)
1853 let registry
= errors
::registry
::Registry
::new(&[]);
1854 let (sessopts
, cfg
) = build_session_options_and_crate_config(matches
);
1855 let sess
= build_session(sessopts
, &dep_graph
, None
, registry
,
1856 Rc
::new(DummyCrateStore
));
1857 let cfg
= build_configuration(&sess
, cfg
);
1858 let mut test_items
= cfg
.iter().filter(|m
| m
.name() == "test");
1859 assert
!(test_items
.next().is_some());
1860 assert
!(test_items
.next().is_none());
1864 fn test_can_print_warnings() {
1865 let dep_graph
= DepGraph
::new(false);
1867 let matches
= getopts(&[
1868 "-Awarnings".to_string()
1869 ], &optgroups()).unwrap();
1870 let registry
= errors
::registry
::Registry
::new(&[]);
1871 let (sessopts
, _
) = build_session_options_and_crate_config(&matches
);
1872 let sess
= build_session(sessopts
, &dep_graph
, None
, registry
,
1873 Rc
::new(DummyCrateStore
));
1874 assert
!(!sess
.diagnostic().can_emit_warnings
);
1878 let matches
= getopts(&[
1879 "-Awarnings".to_string(),
1880 "-Dwarnings".to_string()
1881 ], &optgroups()).unwrap();
1882 let registry
= errors
::registry
::Registry
::new(&[]);
1883 let (sessopts
, _
) = build_session_options_and_crate_config(&matches
);
1884 let sess
= build_session(sessopts
, &dep_graph
, None
, registry
,
1885 Rc
::new(DummyCrateStore
));
1886 assert
!(sess
.diagnostic().can_emit_warnings
);
1890 let matches
= getopts(&[
1891 "-Adead_code".to_string()
1892 ], &optgroups()).unwrap();
1893 let registry
= errors
::registry
::Registry
::new(&[]);
1894 let (sessopts
, _
) = build_session_options_and_crate_config(&matches
);
1895 let sess
= build_session(sessopts
, &dep_graph
, None
, registry
,
1896 Rc
::new(DummyCrateStore
));
1897 assert
!(sess
.diagnostic().can_emit_warnings
);
1902 fn test_output_types_tracking_hash_different_paths() {
1903 let mut v1
= super::basic_options();
1904 let mut v2
= super::basic_options();
1905 let mut v3
= super::basic_options();
1907 v1
.output_types
= OutputTypes
::new(&[(OutputType
::Exe
,
1908 Some(PathBuf
::from("./some/thing")))]);
1909 v2
.output_types
= OutputTypes
::new(&[(OutputType
::Exe
,
1910 Some(PathBuf
::from("/some/thing")))]);
1911 v3
.output_types
= OutputTypes
::new(&[(OutputType
::Exe
, None
)]);
1913 assert
!(v1
.dep_tracking_hash() != v2
.dep_tracking_hash());
1914 assert
!(v1
.dep_tracking_hash() != v3
.dep_tracking_hash());
1915 assert
!(v2
.dep_tracking_hash() != v3
.dep_tracking_hash());
1918 assert_eq
!(v1
.dep_tracking_hash(), v1
.clone().dep_tracking_hash());
1919 assert_eq
!(v2
.dep_tracking_hash(), v2
.clone().dep_tracking_hash());
1920 assert_eq
!(v3
.dep_tracking_hash(), v3
.clone().dep_tracking_hash());
1924 fn test_output_types_tracking_hash_different_construction_order() {
1925 let mut v1
= super::basic_options();
1926 let mut v2
= super::basic_options();
1928 v1
.output_types
= OutputTypes
::new(&[
1929 (OutputType
::Exe
, Some(PathBuf
::from("./some/thing"))),
1930 (OutputType
::Bitcode
, Some(PathBuf
::from("./some/thing.bc"))),
1933 v2
.output_types
= OutputTypes
::new(&[
1934 (OutputType
::Bitcode
, Some(PathBuf
::from("./some/thing.bc"))),
1935 (OutputType
::Exe
, Some(PathBuf
::from("./some/thing"))),
1938 assert_eq
!(v1
.dep_tracking_hash(), v2
.dep_tracking_hash());
1941 assert_eq
!(v1
.dep_tracking_hash(), v1
.clone().dep_tracking_hash());
1945 fn test_externs_tracking_hash_different_values() {
1946 let mut v1
= super::basic_options();
1947 let mut v2
= super::basic_options();
1948 let mut v3
= super::basic_options();
1950 v1
.externs
= Externs
::new(mk_map(vec
![
1951 (String
::from("a"), mk_set(vec
![String
::from("b"),
1952 String
::from("c")])),
1953 (String
::from("d"), mk_set(vec
![String
::from("e"),
1954 String
::from("f")])),
1957 v2
.externs
= Externs
::new(mk_map(vec
![
1958 (String
::from("a"), mk_set(vec
![String
::from("b"),
1959 String
::from("c")])),
1960 (String
::from("X"), mk_set(vec
![String
::from("e"),
1961 String
::from("f")])),
1964 v3
.externs
= Externs
::new(mk_map(vec
![
1965 (String
::from("a"), mk_set(vec
![String
::from("b"),
1966 String
::from("c")])),
1967 (String
::from("d"), mk_set(vec
![String
::from("X"),
1968 String
::from("f")])),
1971 assert
!(v1
.dep_tracking_hash() != v2
.dep_tracking_hash());
1972 assert
!(v1
.dep_tracking_hash() != v3
.dep_tracking_hash());
1973 assert
!(v2
.dep_tracking_hash() != v3
.dep_tracking_hash());
1976 assert_eq
!(v1
.dep_tracking_hash(), v1
.clone().dep_tracking_hash());
1977 assert_eq
!(v2
.dep_tracking_hash(), v2
.clone().dep_tracking_hash());
1978 assert_eq
!(v3
.dep_tracking_hash(), v3
.clone().dep_tracking_hash());
1982 fn test_externs_tracking_hash_different_construction_order() {
1983 let mut v1
= super::basic_options();
1984 let mut v2
= super::basic_options();
1985 let mut v3
= super::basic_options();
1987 v1
.externs
= Externs
::new(mk_map(vec
![
1988 (String
::from("a"), mk_set(vec
![String
::from("b"),
1989 String
::from("c")])),
1990 (String
::from("d"), mk_set(vec
![String
::from("e"),
1991 String
::from("f")])),
1994 v2
.externs
= Externs
::new(mk_map(vec
![
1995 (String
::from("d"), mk_set(vec
![String
::from("e"),
1996 String
::from("f")])),
1997 (String
::from("a"), mk_set(vec
![String
::from("b"),
1998 String
::from("c")])),
2001 v3
.externs
= Externs
::new(mk_map(vec
![
2002 (String
::from("a"), mk_set(vec
![String
::from("b"),
2003 String
::from("c")])),
2004 (String
::from("d"), mk_set(vec
![String
::from("f"),
2005 String
::from("e")])),
2008 assert_eq
!(v1
.dep_tracking_hash(), v2
.dep_tracking_hash());
2009 assert_eq
!(v1
.dep_tracking_hash(), v3
.dep_tracking_hash());
2010 assert_eq
!(v2
.dep_tracking_hash(), v3
.dep_tracking_hash());
2013 assert_eq
!(v1
.dep_tracking_hash(), v1
.clone().dep_tracking_hash());
2014 assert_eq
!(v2
.dep_tracking_hash(), v2
.clone().dep_tracking_hash());
2015 assert_eq
!(v3
.dep_tracking_hash(), v3
.clone().dep_tracking_hash());
2019 fn test_lints_tracking_hash_different_values() {
2020 let mut v1
= super::basic_options();
2021 let mut v2
= super::basic_options();
2022 let mut v3
= super::basic_options();
2024 v1
.lint_opts
= vec
![(String
::from("a"), lint
::Allow
),
2025 (String
::from("b"), lint
::Warn
),
2026 (String
::from("c"), lint
::Deny
),
2027 (String
::from("d"), lint
::Forbid
)];
2029 v2
.lint_opts
= vec
![(String
::from("a"), lint
::Allow
),
2030 (String
::from("b"), lint
::Warn
),
2031 (String
::from("X"), lint
::Deny
),
2032 (String
::from("d"), lint
::Forbid
)];
2034 v3
.lint_opts
= vec
![(String
::from("a"), lint
::Allow
),
2035 (String
::from("b"), lint
::Warn
),
2036 (String
::from("c"), lint
::Forbid
),
2037 (String
::from("d"), lint
::Deny
)];
2039 assert
!(v1
.dep_tracking_hash() != v2
.dep_tracking_hash());
2040 assert
!(v1
.dep_tracking_hash() != v3
.dep_tracking_hash());
2041 assert
!(v2
.dep_tracking_hash() != v3
.dep_tracking_hash());
2044 assert_eq
!(v1
.dep_tracking_hash(), v1
.clone().dep_tracking_hash());
2045 assert_eq
!(v2
.dep_tracking_hash(), v2
.clone().dep_tracking_hash());
2046 assert_eq
!(v3
.dep_tracking_hash(), v3
.clone().dep_tracking_hash());
2050 fn test_lints_tracking_hash_different_construction_order() {
2051 let mut v1
= super::basic_options();
2052 let mut v2
= super::basic_options();
2054 v1
.lint_opts
= vec
![(String
::from("a"), lint
::Allow
),
2055 (String
::from("b"), lint
::Warn
),
2056 (String
::from("c"), lint
::Deny
),
2057 (String
::from("d"), lint
::Forbid
)];
2059 v2
.lint_opts
= vec
![(String
::from("a"), lint
::Allow
),
2060 (String
::from("c"), lint
::Deny
),
2061 (String
::from("b"), lint
::Warn
),
2062 (String
::from("d"), lint
::Forbid
)];
2064 assert_eq
!(v1
.dep_tracking_hash(), v2
.dep_tracking_hash());
2067 assert_eq
!(v1
.dep_tracking_hash(), v1
.clone().dep_tracking_hash());
2068 assert_eq
!(v2
.dep_tracking_hash(), v2
.clone().dep_tracking_hash());
2072 fn test_search_paths_tracking_hash_different_values() {
2073 let mut v1
= super::basic_options();
2074 let mut v2
= super::basic_options();
2075 let mut v3
= super::basic_options();
2076 let mut v4
= super::basic_options();
2077 let mut v5
= super::basic_options();
2080 v1
.search_paths
.add_path("native=abc", super::ErrorOutputType
::Json
);
2081 v1
.search_paths
.add_path("crate=def", super::ErrorOutputType
::Json
);
2082 v1
.search_paths
.add_path("dependency=ghi", super::ErrorOutputType
::Json
);
2083 v1
.search_paths
.add_path("framework=jkl", super::ErrorOutputType
::Json
);
2084 v1
.search_paths
.add_path("all=mno", super::ErrorOutputType
::Json
);
2087 v2
.search_paths
.add_path("native=XXX", super::ErrorOutputType
::Json
);
2088 v2
.search_paths
.add_path("crate=def", super::ErrorOutputType
::Json
);
2089 v2
.search_paths
.add_path("dependency=ghi", super::ErrorOutputType
::Json
);
2090 v2
.search_paths
.add_path("framework=jkl", super::ErrorOutputType
::Json
);
2091 v2
.search_paths
.add_path("all=mno", super::ErrorOutputType
::Json
);
2094 v2
.search_paths
.add_path("native=abc", super::ErrorOutputType
::Json
);
2095 v2
.search_paths
.add_path("crate=XXX", super::ErrorOutputType
::Json
);
2096 v2
.search_paths
.add_path("dependency=ghi", super::ErrorOutputType
::Json
);
2097 v2
.search_paths
.add_path("framework=jkl", super::ErrorOutputType
::Json
);
2098 v2
.search_paths
.add_path("all=mno", super::ErrorOutputType
::Json
);
2100 // Dependency changed
2101 v3
.search_paths
.add_path("native=abc", super::ErrorOutputType
::Json
);
2102 v3
.search_paths
.add_path("crate=def", super::ErrorOutputType
::Json
);
2103 v3
.search_paths
.add_path("dependency=XXX", super::ErrorOutputType
::Json
);
2104 v3
.search_paths
.add_path("framework=jkl", super::ErrorOutputType
::Json
);
2105 v3
.search_paths
.add_path("all=mno", super::ErrorOutputType
::Json
);
2107 // Framework changed
2108 v4
.search_paths
.add_path("native=abc", super::ErrorOutputType
::Json
);
2109 v4
.search_paths
.add_path("crate=def", super::ErrorOutputType
::Json
);
2110 v4
.search_paths
.add_path("dependency=ghi", super::ErrorOutputType
::Json
);
2111 v4
.search_paths
.add_path("framework=XXX", super::ErrorOutputType
::Json
);
2112 v4
.search_paths
.add_path("all=mno", super::ErrorOutputType
::Json
);
2115 v5
.search_paths
.add_path("native=abc", super::ErrorOutputType
::Json
);
2116 v5
.search_paths
.add_path("crate=def", super::ErrorOutputType
::Json
);
2117 v5
.search_paths
.add_path("dependency=ghi", super::ErrorOutputType
::Json
);
2118 v5
.search_paths
.add_path("framework=jkl", super::ErrorOutputType
::Json
);
2119 v5
.search_paths
.add_path("all=XXX", super::ErrorOutputType
::Json
);
2121 assert
!(v1
.dep_tracking_hash() != v2
.dep_tracking_hash());
2122 assert
!(v1
.dep_tracking_hash() != v3
.dep_tracking_hash());
2123 assert
!(v1
.dep_tracking_hash() != v4
.dep_tracking_hash());
2124 assert
!(v1
.dep_tracking_hash() != v5
.dep_tracking_hash());
2127 assert_eq
!(v1
.dep_tracking_hash(), v1
.clone().dep_tracking_hash());
2128 assert_eq
!(v2
.dep_tracking_hash(), v2
.clone().dep_tracking_hash());
2129 assert_eq
!(v3
.dep_tracking_hash(), v3
.clone().dep_tracking_hash());
2130 assert_eq
!(v4
.dep_tracking_hash(), v4
.clone().dep_tracking_hash());
2131 assert_eq
!(v5
.dep_tracking_hash(), v5
.clone().dep_tracking_hash());
2135 fn test_search_paths_tracking_hash_different_order() {
2136 let mut v1
= super::basic_options();
2137 let mut v2
= super::basic_options();
2138 let mut v3
= super::basic_options();
2139 let mut v4
= super::basic_options();
2142 v1
.search_paths
.add_path("native=abc", super::ErrorOutputType
::Json
);
2143 v1
.search_paths
.add_path("crate=def", super::ErrorOutputType
::Json
);
2144 v1
.search_paths
.add_path("dependency=ghi", super::ErrorOutputType
::Json
);
2145 v1
.search_paths
.add_path("framework=jkl", super::ErrorOutputType
::Json
);
2146 v1
.search_paths
.add_path("all=mno", super::ErrorOutputType
::Json
);
2148 v2
.search_paths
.add_path("native=abc", super::ErrorOutputType
::Json
);
2149 v2
.search_paths
.add_path("dependency=ghi", super::ErrorOutputType
::Json
);
2150 v2
.search_paths
.add_path("crate=def", super::ErrorOutputType
::Json
);
2151 v2
.search_paths
.add_path("framework=jkl", super::ErrorOutputType
::Json
);
2152 v2
.search_paths
.add_path("all=mno", super::ErrorOutputType
::Json
);
2154 v3
.search_paths
.add_path("crate=def", super::ErrorOutputType
::Json
);
2155 v3
.search_paths
.add_path("framework=jkl", super::ErrorOutputType
::Json
);
2156 v3
.search_paths
.add_path("native=abc", super::ErrorOutputType
::Json
);
2157 v3
.search_paths
.add_path("dependency=ghi", super::ErrorOutputType
::Json
);
2158 v3
.search_paths
.add_path("all=mno", super::ErrorOutputType
::Json
);
2160 v4
.search_paths
.add_path("all=mno", super::ErrorOutputType
::Json
);
2161 v4
.search_paths
.add_path("native=abc", super::ErrorOutputType
::Json
);
2162 v4
.search_paths
.add_path("crate=def", super::ErrorOutputType
::Json
);
2163 v4
.search_paths
.add_path("dependency=ghi", super::ErrorOutputType
::Json
);
2164 v4
.search_paths
.add_path("framework=jkl", super::ErrorOutputType
::Json
);
2166 assert
!(v1
.dep_tracking_hash() == v2
.dep_tracking_hash());
2167 assert
!(v1
.dep_tracking_hash() == v3
.dep_tracking_hash());
2168 assert
!(v1
.dep_tracking_hash() == v4
.dep_tracking_hash());
2171 assert_eq
!(v1
.dep_tracking_hash(), v1
.clone().dep_tracking_hash());
2172 assert_eq
!(v2
.dep_tracking_hash(), v2
.clone().dep_tracking_hash());
2173 assert_eq
!(v3
.dep_tracking_hash(), v3
.clone().dep_tracking_hash());
2174 assert_eq
!(v4
.dep_tracking_hash(), v4
.clone().dep_tracking_hash());
2178 fn test_native_libs_tracking_hash_different_values() {
2179 let mut v1
= super::basic_options();
2180 let mut v2
= super::basic_options();
2181 let mut v3
= super::basic_options();
2184 v1
.libs
= vec
![(String
::from("a"), cstore
::NativeStatic
),
2185 (String
::from("b"), cstore
::NativeFramework
),
2186 (String
::from("c"), cstore
::NativeUnknown
)];
2189 v2
.libs
= vec
![(String
::from("a"), cstore
::NativeStatic
),
2190 (String
::from("X"), cstore
::NativeFramework
),
2191 (String
::from("c"), cstore
::NativeUnknown
)];
2194 v3
.libs
= vec
![(String
::from("a"), cstore
::NativeStatic
),
2195 (String
::from("b"), cstore
::NativeStatic
),
2196 (String
::from("c"), cstore
::NativeUnknown
)];
2198 assert
!(v1
.dep_tracking_hash() != v2
.dep_tracking_hash());
2199 assert
!(v1
.dep_tracking_hash() != v3
.dep_tracking_hash());
2202 assert_eq
!(v1
.dep_tracking_hash(), v1
.clone().dep_tracking_hash());
2203 assert_eq
!(v2
.dep_tracking_hash(), v2
.clone().dep_tracking_hash());
2204 assert_eq
!(v3
.dep_tracking_hash(), v3
.clone().dep_tracking_hash());
2208 fn test_native_libs_tracking_hash_different_order() {
2209 let mut v1
= super::basic_options();
2210 let mut v2
= super::basic_options();
2211 let mut v3
= super::basic_options();
2214 v1
.libs
= vec
![(String
::from("a"), cstore
::NativeStatic
),
2215 (String
::from("b"), cstore
::NativeFramework
),
2216 (String
::from("c"), cstore
::NativeUnknown
)];
2218 v2
.libs
= vec
![(String
::from("b"), cstore
::NativeFramework
),
2219 (String
::from("a"), cstore
::NativeStatic
),
2220 (String
::from("c"), cstore
::NativeUnknown
)];
2222 v3
.libs
= vec
![(String
::from("c"), cstore
::NativeUnknown
),
2223 (String
::from("a"), cstore
::NativeStatic
),
2224 (String
::from("b"), cstore
::NativeFramework
)];
2226 assert
!(v1
.dep_tracking_hash() == v2
.dep_tracking_hash());
2227 assert
!(v1
.dep_tracking_hash() == v3
.dep_tracking_hash());
2228 assert
!(v2
.dep_tracking_hash() == v3
.dep_tracking_hash());
2231 assert_eq
!(v1
.dep_tracking_hash(), v1
.clone().dep_tracking_hash());
2232 assert_eq
!(v2
.dep_tracking_hash(), v2
.clone().dep_tracking_hash());
2233 assert_eq
!(v3
.dep_tracking_hash(), v3
.clone().dep_tracking_hash());
2237 fn test_codegen_options_tracking_hash() {
2238 let reference
= super::basic_options();
2239 let mut opts
= super::basic_options();
2241 // Make sure the changing an [UNTRACKED] option leaves the hash unchanged
2242 opts
.cg
.ar
= Some(String
::from("abc"));
2243 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2245 opts
.cg
.linker
= Some(String
::from("linker"));
2246 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2248 opts
.cg
.link_args
= Some(vec
![String
::from("abc"), String
::from("def")]);
2249 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2251 opts
.cg
.link_dead_code
= true;
2252 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2254 opts
.cg
.rpath
= true;
2255 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2257 opts
.cg
.extra_filename
= String
::from("extra-filename");
2258 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2260 opts
.cg
.codegen_units
= 42;
2261 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2263 opts
.cg
.remark
= super::SomePasses(vec
![String
::from("pass1"),
2264 String
::from("pass2")]);
2265 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2267 opts
.cg
.save_temps
= true;
2268 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2271 // Make sure changing a [TRACKED] option changes the hash
2272 opts
= reference
.clone();
2274 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2276 opts
= reference
.clone();
2277 opts
.cg
.target_cpu
= Some(String
::from("abc"));
2278 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2280 opts
= reference
.clone();
2281 opts
.cg
.target_feature
= String
::from("all the features, all of them");
2282 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2284 opts
= reference
.clone();
2285 opts
.cg
.passes
= vec
![String
::from("1"), String
::from("2")];
2286 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2288 opts
= reference
.clone();
2289 opts
.cg
.llvm_args
= vec
![String
::from("1"), String
::from("2")];
2290 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2292 opts
= reference
.clone();
2293 opts
.cg
.no_prepopulate_passes
= true;
2294 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2296 opts
= reference
.clone();
2297 opts
.cg
.no_vectorize_loops
= true;
2298 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2300 opts
= reference
.clone();
2301 opts
.cg
.no_vectorize_slp
= true;
2302 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2304 opts
= reference
.clone();
2305 opts
.cg
.soft_float
= true;
2306 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2308 opts
= reference
.clone();
2309 opts
.cg
.prefer_dynamic
= true;
2310 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2312 opts
= reference
.clone();
2313 opts
.cg
.no_integrated_as
= true;
2314 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2316 opts
= reference
.clone();
2317 opts
.cg
.no_redzone
= Some(true);
2318 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2320 opts
= reference
.clone();
2321 opts
.cg
.relocation_model
= Some(String
::from("relocation model"));
2322 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2324 opts
= reference
.clone();
2325 opts
.cg
.code_model
= Some(String
::from("code model"));
2326 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2328 opts
= reference
.clone();
2329 opts
.cg
.metadata
= vec
![String
::from("A"), String
::from("B")];
2330 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2332 opts
= reference
.clone();
2333 opts
.cg
.debuginfo
= Some(0xdeadbeef);
2334 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2336 opts
= reference
.clone();
2337 opts
.cg
.debuginfo
= Some(0xba5eba11);
2338 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2340 opts
= reference
.clone();
2341 opts
.cg
.debug_assertions
= Some(true);
2342 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2344 opts
= reference
.clone();
2345 opts
.cg
.inline_threshold
= Some(0xf007ba11);
2346 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2348 opts
= reference
.clone();
2349 opts
.cg
.panic
= PanicStrategy
::Abort
;
2350 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2354 fn test_debugging_options_tracking_hash() {
2355 let reference
= super::basic_options();
2356 let mut opts
= super::basic_options();
2358 // Make sure the changing an [UNTRACKED] option leaves the hash unchanged
2359 opts
.debugging_opts
.verbose
= true;
2360 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2361 opts
.debugging_opts
.time_passes
= true;
2362 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2363 opts
.debugging_opts
.count_llvm_insns
= true;
2364 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2365 opts
.debugging_opts
.time_llvm_passes
= true;
2366 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2367 opts
.debugging_opts
.input_stats
= true;
2368 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2369 opts
.debugging_opts
.trans_stats
= true;
2370 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2371 opts
.debugging_opts
.borrowck_stats
= true;
2372 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2373 opts
.debugging_opts
.debug_llvm
= true;
2374 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2375 opts
.debugging_opts
.meta_stats
= true;
2376 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2377 opts
.debugging_opts
.print_link_args
= true;
2378 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2379 opts
.debugging_opts
.print_llvm_passes
= true;
2380 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2381 opts
.debugging_opts
.ast_json
= true;
2382 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2383 opts
.debugging_opts
.ast_json_noexpand
= true;
2384 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2385 opts
.debugging_opts
.ls
= true;
2386 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2387 opts
.debugging_opts
.save_analysis
= true;
2388 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2389 opts
.debugging_opts
.save_analysis_csv
= true;
2390 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2391 opts
.debugging_opts
.print_move_fragments
= true;
2392 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2393 opts
.debugging_opts
.flowgraph_print_loans
= true;
2394 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2395 opts
.debugging_opts
.flowgraph_print_moves
= true;
2396 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2397 opts
.debugging_opts
.flowgraph_print_assigns
= true;
2398 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2399 opts
.debugging_opts
.flowgraph_print_all
= true;
2400 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2401 opts
.debugging_opts
.print_region_graph
= true;
2402 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2403 opts
.debugging_opts
.parse_only
= true;
2404 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2405 opts
.debugging_opts
.incremental
= Some(String
::from("abc"));
2406 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2407 opts
.debugging_opts
.dump_dep_graph
= true;
2408 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2409 opts
.debugging_opts
.query_dep_graph
= true;
2410 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2411 opts
.debugging_opts
.no_analysis
= true;
2412 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2413 opts
.debugging_opts
.unstable_options
= true;
2414 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2415 opts
.debugging_opts
.trace_macros
= true;
2416 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2417 opts
.debugging_opts
.keep_hygiene_data
= true;
2418 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2419 opts
.debugging_opts
.keep_ast
= true;
2420 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2421 opts
.debugging_opts
.print_trans_items
= Some(String
::from("abc"));
2422 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2423 opts
.debugging_opts
.dump_mir
= Some(String
::from("abc"));
2424 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2425 opts
.debugging_opts
.dump_mir_dir
= Some(String
::from("abc"));
2426 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2427 opts
.debugging_opts
.orbit
= false;
2428 assert_eq
!(reference
.dep_tracking_hash(), opts
.dep_tracking_hash());
2430 // Make sure changing a [TRACKED] option changes the hash
2431 opts
= reference
.clone();
2432 opts
.debugging_opts
.asm_comments
= true;
2433 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2435 opts
= reference
.clone();
2436 opts
.debugging_opts
.no_verify
= true;
2437 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2439 opts
= reference
.clone();
2440 opts
.debugging_opts
.no_landing_pads
= true;
2441 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2443 opts
= reference
.clone();
2444 opts
.debugging_opts
.no_trans
= true;
2445 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2447 opts
= reference
.clone();
2448 opts
.debugging_opts
.treat_err_as_bug
= true;
2449 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2451 opts
= reference
.clone();
2452 opts
.debugging_opts
.continue_parse_after_error
= true;
2453 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2455 opts
= reference
.clone();
2456 opts
.debugging_opts
.extra_plugins
= vec
![String
::from("plugin1"), String
::from("plugin2")];
2457 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2459 opts
= reference
.clone();
2460 opts
.debugging_opts
.force_overflow_checks
= Some(true);
2461 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2463 opts
= reference
.clone();
2464 opts
.debugging_opts
.force_dropflag_checks
= Some(true);
2465 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2467 opts
= reference
.clone();
2468 opts
.debugging_opts
.enable_nonzeroing_move_hints
= true;
2469 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2471 opts
= reference
.clone();
2472 opts
.debugging_opts
.show_span
= Some(String
::from("abc"));
2473 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());
2475 opts
= reference
.clone();
2476 opts
.debugging_opts
.mir_opt_level
= Some(1);
2477 assert
!(reference
.dep_tracking_hash() != opts
.dep_tracking_hash());