]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_interface/src/tests.rs
Rollup merge of #91329 - Aaron1011:modulo-regions-test, r=jackh726
[rust.git] / compiler / rustc_interface / src / tests.rs
1 use crate::interface::parse_cfgspecs;
2
3 use rustc_data_structures::fx::FxHashSet;
4 use rustc_errors::{emitter::HumanReadableErrorType, registry, ColorConfig};
5 use rustc_session::config::InstrumentCoverage;
6 use rustc_session::config::Strip;
7 use rustc_session::config::{build_configuration, build_session_options, to_crate_config};
8 use rustc_session::config::{
9     rustc_optgroups, ErrorOutputType, ExternLocation, LocationDetail, Options, Passes,
10 };
11 use rustc_session::config::{CFGuard, ExternEntry, LinkerPluginLto, LtoCli, SwitchWithOptPath};
12 use rustc_session::config::{
13     Externs, OutputType, OutputTypes, SymbolManglingVersion, WasiExecModel,
14 };
15 use rustc_session::lint::Level;
16 use rustc_session::search_paths::SearchPath;
17 use rustc_session::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
18 use rustc_session::{build_session, getopts, DiagnosticOutput, Session};
19 use rustc_span::edition::{Edition, DEFAULT_EDITION};
20 use rustc_span::symbol::sym;
21 use rustc_span::SourceFileHashAlgorithm;
22 use rustc_target::spec::{CodeModel, LinkerFlavor, MergeFunctions, PanicStrategy};
23 use rustc_target::spec::{
24     RelocModel, RelroLevel, SanitizerSet, SplitDebuginfo, StackProtector, TlsModel,
25 };
26
27 use std::collections::{BTreeMap, BTreeSet};
28 use std::iter::FromIterator;
29 use std::num::NonZeroUsize;
30 use std::path::{Path, PathBuf};
31
32 type CfgSpecs = FxHashSet<(String, Option<String>)>;
33
34 fn build_session_options_and_crate_config(matches: getopts::Matches) -> (Options, CfgSpecs) {
35     let sessopts = build_session_options(&matches);
36     let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
37     (sessopts, cfg)
38 }
39
40 fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
41     let registry = registry::Registry::new(&[]);
42     let (sessopts, cfg) = build_session_options_and_crate_config(matches);
43     let sess = build_session(
44         sessopts,
45         None,
46         registry,
47         DiagnosticOutput::Default,
48         Default::default(),
49         None,
50         None,
51     );
52     (sess, cfg)
53 }
54
55 fn new_public_extern_entry<S, I>(locations: I) -> ExternEntry
56 where
57     S: Into<String>,
58     I: IntoIterator<Item = S>,
59 {
60     let locations: BTreeSet<CanonicalizedPath> =
61         locations.into_iter().map(|s| CanonicalizedPath::new(Path::new(&s.into()))).collect();
62
63     ExternEntry {
64         location: ExternLocation::ExactPaths(locations),
65         is_private_dep: false,
66         add_prelude: true,
67     }
68 }
69
70 fn optgroups() -> getopts::Options {
71     let mut opts = getopts::Options::new();
72     for group in rustc_optgroups() {
73         (group.apply)(&mut opts);
74     }
75     return opts;
76 }
77
78 fn mk_map<K: Ord, V>(entries: Vec<(K, V)>) -> BTreeMap<K, V> {
79     BTreeMap::from_iter(entries.into_iter())
80 }
81
82 fn assert_same_clone(x: &Options) {
83     assert_eq!(x.dep_tracking_hash(true), x.clone().dep_tracking_hash(true));
84     assert_eq!(x.dep_tracking_hash(false), x.clone().dep_tracking_hash(false));
85 }
86
87 fn assert_same_hash(x: &Options, y: &Options) {
88     assert_eq!(x.dep_tracking_hash(true), y.dep_tracking_hash(true));
89     assert_eq!(x.dep_tracking_hash(false), y.dep_tracking_hash(false));
90     // Check clone
91     assert_same_clone(x);
92     assert_same_clone(y);
93 }
94
95 fn assert_different_hash(x: &Options, y: &Options) {
96     assert_ne!(x.dep_tracking_hash(true), y.dep_tracking_hash(true));
97     assert_ne!(x.dep_tracking_hash(false), y.dep_tracking_hash(false));
98     // Check clone
99     assert_same_clone(x);
100     assert_same_clone(y);
101 }
102
103 fn assert_non_crate_hash_different(x: &Options, y: &Options) {
104     assert_eq!(x.dep_tracking_hash(true), y.dep_tracking_hash(true));
105     assert_ne!(x.dep_tracking_hash(false), y.dep_tracking_hash(false));
106     // Check clone
107     assert_same_clone(x);
108     assert_same_clone(y);
109 }
110
111 // When the user supplies --test we should implicitly supply --cfg test
112 #[test]
113 fn test_switch_implies_cfg_test() {
114     rustc_span::create_default_session_globals_then(|| {
115         let matches = optgroups().parse(&["--test".to_string()]).unwrap();
116         let (sess, cfg) = mk_session(matches);
117         let cfg = build_configuration(&sess, to_crate_config(cfg));
118         assert!(cfg.contains(&(sym::test, None)));
119     });
120 }
121
122 // When the user supplies --test and --cfg test, don't implicitly add another --cfg test
123 #[test]
124 fn test_switch_implies_cfg_test_unless_cfg_test() {
125     rustc_span::create_default_session_globals_then(|| {
126         let matches = optgroups().parse(&["--test".to_string(), "--cfg=test".to_string()]).unwrap();
127         let (sess, cfg) = mk_session(matches);
128         let cfg = build_configuration(&sess, to_crate_config(cfg));
129         let mut test_items = cfg.iter().filter(|&&(name, _)| name == sym::test);
130         assert!(test_items.next().is_some());
131         assert!(test_items.next().is_none());
132     });
133 }
134
135 #[test]
136 fn test_can_print_warnings() {
137     rustc_span::create_default_session_globals_then(|| {
138         let matches = optgroups().parse(&["-Awarnings".to_string()]).unwrap();
139         let (sess, _) = mk_session(matches);
140         assert!(!sess.diagnostic().can_emit_warnings());
141     });
142
143     rustc_span::create_default_session_globals_then(|| {
144         let matches =
145             optgroups().parse(&["-Awarnings".to_string(), "-Dwarnings".to_string()]).unwrap();
146         let (sess, _) = mk_session(matches);
147         assert!(sess.diagnostic().can_emit_warnings());
148     });
149
150     rustc_span::create_default_session_globals_then(|| {
151         let matches = optgroups().parse(&["-Adead_code".to_string()]).unwrap();
152         let (sess, _) = mk_session(matches);
153         assert!(sess.diagnostic().can_emit_warnings());
154     });
155 }
156
157 #[test]
158 fn test_output_types_tracking_hash_different_paths() {
159     let mut v1 = Options::default();
160     let mut v2 = Options::default();
161     let mut v3 = Options::default();
162
163     v1.output_types = OutputTypes::new(&[(OutputType::Exe, Some(PathBuf::from("./some/thing")))]);
164     v2.output_types = OutputTypes::new(&[(OutputType::Exe, Some(PathBuf::from("/some/thing")))]);
165     v3.output_types = OutputTypes::new(&[(OutputType::Exe, None)]);
166
167     assert_non_crate_hash_different(&v1, &v2);
168     assert_non_crate_hash_different(&v1, &v3);
169     assert_non_crate_hash_different(&v2, &v3);
170 }
171
172 #[test]
173 fn test_output_types_tracking_hash_different_construction_order() {
174     let mut v1 = Options::default();
175     let mut v2 = Options::default();
176
177     v1.output_types = OutputTypes::new(&[
178         (OutputType::Exe, Some(PathBuf::from("./some/thing"))),
179         (OutputType::Bitcode, Some(PathBuf::from("./some/thing.bc"))),
180     ]);
181
182     v2.output_types = OutputTypes::new(&[
183         (OutputType::Bitcode, Some(PathBuf::from("./some/thing.bc"))),
184         (OutputType::Exe, Some(PathBuf::from("./some/thing"))),
185     ]);
186
187     assert_same_hash(&v1, &v2);
188 }
189
190 #[test]
191 fn test_externs_tracking_hash_different_construction_order() {
192     let mut v1 = Options::default();
193     let mut v2 = Options::default();
194     let mut v3 = Options::default();
195
196     v1.externs = Externs::new(mk_map(vec![
197         (String::from("a"), new_public_extern_entry(vec!["b", "c"])),
198         (String::from("d"), new_public_extern_entry(vec!["e", "f"])),
199     ]));
200
201     v2.externs = Externs::new(mk_map(vec![
202         (String::from("d"), new_public_extern_entry(vec!["e", "f"])),
203         (String::from("a"), new_public_extern_entry(vec!["b", "c"])),
204     ]));
205
206     v3.externs = Externs::new(mk_map(vec![
207         (String::from("a"), new_public_extern_entry(vec!["b", "c"])),
208         (String::from("d"), new_public_extern_entry(vec!["f", "e"])),
209     ]));
210
211     assert_same_hash(&v1, &v2);
212     assert_same_hash(&v1, &v3);
213     assert_same_hash(&v2, &v3);
214 }
215
216 #[test]
217 fn test_lints_tracking_hash_different_values() {
218     let mut v1 = Options::default();
219     let mut v2 = Options::default();
220     let mut v3 = Options::default();
221
222     v1.lint_opts = vec![
223         (String::from("a"), Level::Allow),
224         (String::from("b"), Level::Warn),
225         (String::from("c"), Level::Deny),
226         (String::from("d"), Level::Forbid),
227     ];
228
229     v2.lint_opts = vec![
230         (String::from("a"), Level::Allow),
231         (String::from("b"), Level::Warn),
232         (String::from("X"), Level::Deny),
233         (String::from("d"), Level::Forbid),
234     ];
235
236     v3.lint_opts = vec![
237         (String::from("a"), Level::Allow),
238         (String::from("b"), Level::Warn),
239         (String::from("c"), Level::Forbid),
240         (String::from("d"), Level::Deny),
241     ];
242
243     assert_non_crate_hash_different(&v1, &v2);
244     assert_non_crate_hash_different(&v1, &v3);
245     assert_non_crate_hash_different(&v2, &v3);
246 }
247
248 #[test]
249 fn test_lints_tracking_hash_different_construction_order() {
250     let mut v1 = Options::default();
251     let mut v2 = Options::default();
252
253     v1.lint_opts = vec![
254         (String::from("a"), Level::Allow),
255         (String::from("b"), Level::Warn),
256         (String::from("c"), Level::Deny),
257         (String::from("d"), Level::Forbid),
258     ];
259
260     v2.lint_opts = vec![
261         (String::from("a"), Level::Allow),
262         (String::from("c"), Level::Deny),
263         (String::from("b"), Level::Warn),
264         (String::from("d"), Level::Forbid),
265     ];
266
267     // The hash should be order-dependent
268     assert_non_crate_hash_different(&v1, &v2);
269 }
270
271 #[test]
272 fn test_lint_cap_hash_different() {
273     let mut v1 = Options::default();
274     let mut v2 = Options::default();
275     let v3 = Options::default();
276
277     v1.lint_cap = Some(Level::Forbid);
278     v2.lint_cap = Some(Level::Allow);
279
280     assert_non_crate_hash_different(&v1, &v2);
281     assert_non_crate_hash_different(&v1, &v3);
282     assert_non_crate_hash_different(&v2, &v3);
283 }
284
285 #[test]
286 fn test_search_paths_tracking_hash_different_order() {
287     let mut v1 = Options::default();
288     let mut v2 = Options::default();
289     let mut v3 = Options::default();
290     let mut v4 = Options::default();
291
292     const JSON: ErrorOutputType = ErrorOutputType::Json {
293         pretty: false,
294         json_rendered: HumanReadableErrorType::Default(ColorConfig::Never),
295     };
296
297     // Reference
298     v1.search_paths.push(SearchPath::from_cli_opt("native=abc", JSON));
299     v1.search_paths.push(SearchPath::from_cli_opt("crate=def", JSON));
300     v1.search_paths.push(SearchPath::from_cli_opt("dependency=ghi", JSON));
301     v1.search_paths.push(SearchPath::from_cli_opt("framework=jkl", JSON));
302     v1.search_paths.push(SearchPath::from_cli_opt("all=mno", JSON));
303
304     v2.search_paths.push(SearchPath::from_cli_opt("native=abc", JSON));
305     v2.search_paths.push(SearchPath::from_cli_opt("dependency=ghi", JSON));
306     v2.search_paths.push(SearchPath::from_cli_opt("crate=def", JSON));
307     v2.search_paths.push(SearchPath::from_cli_opt("framework=jkl", JSON));
308     v2.search_paths.push(SearchPath::from_cli_opt("all=mno", JSON));
309
310     v3.search_paths.push(SearchPath::from_cli_opt("crate=def", JSON));
311     v3.search_paths.push(SearchPath::from_cli_opt("framework=jkl", JSON));
312     v3.search_paths.push(SearchPath::from_cli_opt("native=abc", JSON));
313     v3.search_paths.push(SearchPath::from_cli_opt("dependency=ghi", JSON));
314     v3.search_paths.push(SearchPath::from_cli_opt("all=mno", JSON));
315
316     v4.search_paths.push(SearchPath::from_cli_opt("all=mno", JSON));
317     v4.search_paths.push(SearchPath::from_cli_opt("native=abc", JSON));
318     v4.search_paths.push(SearchPath::from_cli_opt("crate=def", JSON));
319     v4.search_paths.push(SearchPath::from_cli_opt("dependency=ghi", JSON));
320     v4.search_paths.push(SearchPath::from_cli_opt("framework=jkl", JSON));
321
322     assert_same_hash(&v1, &v2);
323     assert_same_hash(&v1, &v3);
324     assert_same_hash(&v1, &v4);
325 }
326
327 #[test]
328 fn test_native_libs_tracking_hash_different_values() {
329     let mut v1 = Options::default();
330     let mut v2 = Options::default();
331     let mut v3 = Options::default();
332     let mut v4 = Options::default();
333     let mut v5 = Options::default();
334
335     // Reference
336     v1.libs = vec![
337         NativeLib {
338             name: String::from("a"),
339             new_name: None,
340             kind: NativeLibKind::Static { bundle: None, whole_archive: None },
341             verbatim: None,
342         },
343         NativeLib {
344             name: String::from("b"),
345             new_name: None,
346             kind: NativeLibKind::Framework { as_needed: None },
347             verbatim: None,
348         },
349         NativeLib {
350             name: String::from("c"),
351             new_name: None,
352             kind: NativeLibKind::Unspecified,
353             verbatim: None,
354         },
355     ];
356
357     // Change label
358     v2.libs = vec![
359         NativeLib {
360             name: String::from("a"),
361             new_name: None,
362             kind: NativeLibKind::Static { bundle: None, whole_archive: None },
363             verbatim: None,
364         },
365         NativeLib {
366             name: String::from("X"),
367             new_name: None,
368             kind: NativeLibKind::Framework { as_needed: None },
369             verbatim: None,
370         },
371         NativeLib {
372             name: String::from("c"),
373             new_name: None,
374             kind: NativeLibKind::Unspecified,
375             verbatim: None,
376         },
377     ];
378
379     // Change kind
380     v3.libs = vec![
381         NativeLib {
382             name: String::from("a"),
383             new_name: None,
384             kind: NativeLibKind::Static { bundle: None, whole_archive: None },
385             verbatim: None,
386         },
387         NativeLib {
388             name: String::from("b"),
389             new_name: None,
390             kind: NativeLibKind::Static { bundle: None, whole_archive: None },
391             verbatim: None,
392         },
393         NativeLib {
394             name: String::from("c"),
395             new_name: None,
396             kind: NativeLibKind::Unspecified,
397             verbatim: None,
398         },
399     ];
400
401     // Change new-name
402     v4.libs = vec![
403         NativeLib {
404             name: String::from("a"),
405             new_name: None,
406             kind: NativeLibKind::Static { bundle: None, whole_archive: None },
407             verbatim: None,
408         },
409         NativeLib {
410             name: String::from("b"),
411             new_name: Some(String::from("X")),
412             kind: NativeLibKind::Framework { as_needed: None },
413             verbatim: None,
414         },
415         NativeLib {
416             name: String::from("c"),
417             new_name: None,
418             kind: NativeLibKind::Unspecified,
419             verbatim: None,
420         },
421     ];
422
423     // Change verbatim
424     v5.libs = vec![
425         NativeLib {
426             name: String::from("a"),
427             new_name: None,
428             kind: NativeLibKind::Static { bundle: None, whole_archive: None },
429             verbatim: None,
430         },
431         NativeLib {
432             name: String::from("b"),
433             new_name: None,
434             kind: NativeLibKind::Framework { as_needed: None },
435             verbatim: Some(true),
436         },
437         NativeLib {
438             name: String::from("c"),
439             new_name: None,
440             kind: NativeLibKind::Unspecified,
441             verbatim: None,
442         },
443     ];
444
445     assert_different_hash(&v1, &v2);
446     assert_different_hash(&v1, &v3);
447     assert_different_hash(&v1, &v4);
448     assert_different_hash(&v1, &v5);
449 }
450
451 #[test]
452 fn test_native_libs_tracking_hash_different_order() {
453     let mut v1 = Options::default();
454     let mut v2 = Options::default();
455     let mut v3 = Options::default();
456
457     // Reference
458     v1.libs = vec![
459         NativeLib {
460             name: String::from("a"),
461             new_name: None,
462             kind: NativeLibKind::Static { bundle: None, whole_archive: None },
463             verbatim: None,
464         },
465         NativeLib {
466             name: String::from("b"),
467             new_name: None,
468             kind: NativeLibKind::Framework { as_needed: None },
469             verbatim: None,
470         },
471         NativeLib {
472             name: String::from("c"),
473             new_name: None,
474             kind: NativeLibKind::Unspecified,
475             verbatim: None,
476         },
477     ];
478
479     v2.libs = vec![
480         NativeLib {
481             name: String::from("b"),
482             new_name: None,
483             kind: NativeLibKind::Framework { as_needed: None },
484             verbatim: None,
485         },
486         NativeLib {
487             name: String::from("a"),
488             new_name: None,
489             kind: NativeLibKind::Static { bundle: None, whole_archive: None },
490             verbatim: None,
491         },
492         NativeLib {
493             name: String::from("c"),
494             new_name: None,
495             kind: NativeLibKind::Unspecified,
496             verbatim: None,
497         },
498     ];
499
500     v3.libs = vec![
501         NativeLib {
502             name: String::from("c"),
503             new_name: None,
504             kind: NativeLibKind::Unspecified,
505             verbatim: None,
506         },
507         NativeLib {
508             name: String::from("a"),
509             new_name: None,
510             kind: NativeLibKind::Static { bundle: None, whole_archive: None },
511             verbatim: None,
512         },
513         NativeLib {
514             name: String::from("b"),
515             new_name: None,
516             kind: NativeLibKind::Framework { as_needed: None },
517             verbatim: None,
518         },
519     ];
520
521     // The hash should be order-dependent
522     assert_different_hash(&v1, &v2);
523     assert_different_hash(&v1, &v3);
524     assert_different_hash(&v2, &v3);
525 }
526
527 #[test]
528 fn test_codegen_options_tracking_hash() {
529     let reference = Options::default();
530     let mut opts = Options::default();
531
532     macro_rules! untracked {
533         ($name: ident, $non_default_value: expr) => {
534             assert_ne!(opts.cg.$name, $non_default_value);
535             opts.cg.$name = $non_default_value;
536             assert_same_hash(&reference, &opts);
537         };
538     }
539
540     // Make sure that changing an [UNTRACKED] option leaves the hash unchanged.
541     // This list is in alphabetical order.
542     untracked!(ar, String::from("abc"));
543     untracked!(codegen_units, Some(42));
544     untracked!(default_linker_libraries, true);
545     untracked!(extra_filename, String::from("extra-filename"));
546     untracked!(incremental, Some(String::from("abc")));
547     // `link_arg` is omitted because it just forwards to `link_args`.
548     untracked!(link_args, vec![String::from("abc"), String::from("def")]);
549     untracked!(link_self_contained, Some(true));
550     untracked!(linker, Some(PathBuf::from("linker")));
551     untracked!(linker_flavor, Some(LinkerFlavor::Gcc));
552     untracked!(no_stack_check, true);
553     untracked!(remark, Passes::Some(vec![String::from("pass1"), String::from("pass2")]));
554     untracked!(rpath, true);
555     untracked!(save_temps, true);
556     untracked!(strip, Strip::Debuginfo);
557
558     macro_rules! tracked {
559         ($name: ident, $non_default_value: expr) => {
560             opts = reference.clone();
561             assert_ne!(opts.cg.$name, $non_default_value);
562             opts.cg.$name = $non_default_value;
563             assert_different_hash(&reference, &opts);
564         };
565     }
566
567     // Make sure that changing a [TRACKED] option changes the hash.
568     // This list is in alphabetical order.
569     tracked!(code_model, Some(CodeModel::Large));
570     tracked!(control_flow_guard, CFGuard::Checks);
571     tracked!(debug_assertions, Some(true));
572     tracked!(debuginfo, 0xdeadbeef);
573     tracked!(embed_bitcode, false);
574     tracked!(force_frame_pointers, Some(false));
575     tracked!(force_unwind_tables, Some(true));
576     tracked!(inline_threshold, Some(0xf007ba11));
577     tracked!(linker_plugin_lto, LinkerPluginLto::LinkerPluginAuto);
578     tracked!(link_dead_code, Some(true));
579     tracked!(llvm_args, vec![String::from("1"), String::from("2")]);
580     tracked!(lto, LtoCli::Fat);
581     tracked!(metadata, vec![String::from("A"), String::from("B")]);
582     tracked!(no_prepopulate_passes, true);
583     tracked!(no_redzone, Some(true));
584     tracked!(no_vectorize_loops, true);
585     tracked!(no_vectorize_slp, true);
586     tracked!(opt_level, "3".to_string());
587     tracked!(overflow_checks, Some(true));
588     tracked!(panic, Some(PanicStrategy::Abort));
589     tracked!(passes, vec![String::from("1"), String::from("2")]);
590     tracked!(prefer_dynamic, true);
591     tracked!(profile_generate, SwitchWithOptPath::Enabled(None));
592     tracked!(profile_use, Some(PathBuf::from("abc")));
593     tracked!(relocation_model, Some(RelocModel::Pic));
594     tracked!(soft_float, true);
595     tracked!(split_debuginfo, Some(SplitDebuginfo::Packed));
596     tracked!(target_cpu, Some(String::from("abc")));
597     tracked!(target_feature, String::from("all the features, all of them"));
598 }
599
600 #[test]
601 fn test_top_level_options_tracked_no_crate() {
602     let reference = Options::default();
603     let mut opts;
604
605     macro_rules! tracked {
606         ($name: ident, $non_default_value: expr) => {
607             opts = reference.clone();
608             assert_ne!(opts.$name, $non_default_value);
609             opts.$name = $non_default_value;
610             // The crate hash should be the same
611             assert_eq!(reference.dep_tracking_hash(true), opts.dep_tracking_hash(true));
612             // The incremental hash should be different
613             assert_ne!(reference.dep_tracking_hash(false), opts.dep_tracking_hash(false));
614         };
615     }
616
617     // Make sure that changing a [TRACKED_NO_CRATE_HASH] option leaves the crate hash unchanged but changes the incremental hash.
618     // This list is in alphabetical order.
619     tracked!(remap_path_prefix, vec![("/home/bors/rust".into(), "src".into())]);
620     tracked!(
621         real_rust_source_base_dir,
622         Some("/home/bors/rust/.rustup/toolchains/nightly/lib/rustlib/src/rust".into())
623     );
624 }
625
626 #[test]
627 fn test_debugging_options_tracking_hash() {
628     let reference = Options::default();
629     let mut opts = Options::default();
630
631     macro_rules! untracked {
632         ($name: ident, $non_default_value: expr) => {
633             assert_ne!(opts.debugging_opts.$name, $non_default_value);
634             opts.debugging_opts.$name = $non_default_value;
635             assert_same_hash(&reference, &opts);
636         };
637     }
638
639     // Make sure that changing an [UNTRACKED] option leaves the hash unchanged.
640     // This list is in alphabetical order.
641     untracked!(assert_incr_state, Some(String::from("loaded")));
642     untracked!(ast_json, true);
643     untracked!(ast_json_noexpand, true);
644     untracked!(borrowck, String::from("other"));
645     untracked!(deduplicate_diagnostics, false);
646     untracked!(dep_tasks, true);
647     untracked!(dont_buffer_diagnostics, true);
648     untracked!(dump_dep_graph, true);
649     untracked!(dump_mir, Some(String::from("abc")));
650     untracked!(dump_mir_dataflow, true);
651     untracked!(dump_mir_dir, String::from("abc"));
652     untracked!(dump_mir_exclude_pass_number, true);
653     untracked!(dump_mir_graphviz, true);
654     untracked!(emit_future_incompat_report, true);
655     untracked!(emit_stack_sizes, true);
656     untracked!(future_incompat_test, true);
657     untracked!(hir_stats, true);
658     untracked!(identify_regions, true);
659     untracked!(incremental_ignore_spans, true);
660     untracked!(incremental_info, true);
661     untracked!(incremental_verify_ich, true);
662     untracked!(input_stats, true);
663     untracked!(keep_hygiene_data, true);
664     untracked!(link_native_libraries, false);
665     untracked!(llvm_time_trace, true);
666     untracked!(ls, true);
667     untracked!(macro_backtrace, true);
668     untracked!(meta_stats, true);
669     untracked!(nll_facts, true);
670     untracked!(no_analysis, true);
671     untracked!(no_interleave_lints, true);
672     untracked!(no_leak_check, true);
673     untracked!(no_parallel_llvm, true);
674     untracked!(parse_only, true);
675     untracked!(perf_stats, true);
676     // `pre_link_arg` is omitted because it just forwards to `pre_link_args`.
677     untracked!(pre_link_args, vec![String::from("abc"), String::from("def")]);
678     untracked!(profile_closures, true);
679     untracked!(print_link_args, true);
680     untracked!(print_llvm_passes, true);
681     untracked!(print_mono_items, Some(String::from("abc")));
682     untracked!(print_type_sizes, true);
683     untracked!(proc_macro_backtrace, true);
684     untracked!(query_dep_graph, true);
685     untracked!(query_stats, true);
686     untracked!(save_analysis, true);
687     untracked!(self_profile, SwitchWithOptPath::Enabled(None));
688     untracked!(self_profile_events, Some(vec![String::new()]));
689     untracked!(span_debug, true);
690     untracked!(span_free_formats, true);
691     untracked!(temps_dir, Some(String::from("abc")));
692     untracked!(terminal_width, Some(80));
693     untracked!(threads, 99);
694     untracked!(time, true);
695     untracked!(time_llvm_passes, true);
696     untracked!(time_passes, true);
697     untracked!(trace_macros, true);
698     untracked!(trim_diagnostic_paths, false);
699     untracked!(ui_testing, true);
700     untracked!(unpretty, Some("expanded".to_string()));
701     untracked!(unstable_options, true);
702     untracked!(validate_mir, true);
703     untracked!(verbose, true);
704
705     macro_rules! tracked {
706         ($name: ident, $non_default_value: expr) => {
707             opts = reference.clone();
708             assert_ne!(opts.debugging_opts.$name, $non_default_value);
709             opts.debugging_opts.$name = $non_default_value;
710             assert_different_hash(&reference, &opts);
711         };
712     }
713
714     // Make sure that changing a [TRACKED] option changes the hash.
715     // This list is in alphabetical order.
716     tracked!(allow_features, Some(vec![String::from("lang_items")]));
717     tracked!(always_encode_mir, true);
718     tracked!(asm_comments, true);
719     tracked!(assume_incomplete_release, true);
720     tracked!(binary_dep_depinfo, true);
721     tracked!(chalk, true);
722     tracked!(codegen_backend, Some("abc".to_string()));
723     tracked!(crate_attr, vec!["abc".to_string()]);
724     tracked!(debug_info_for_profiling, true);
725     tracked!(debug_macros, true);
726     tracked!(dep_info_omit_d_target, true);
727     tracked!(dual_proc_macros, true);
728     tracked!(fewer_names, Some(true));
729     tracked!(force_unstable_if_unmarked, true);
730     tracked!(fuel, Some(("abc".to_string(), 99)));
731     tracked!(function_sections, Some(false));
732     tracked!(human_readable_cgu_names, true);
733     tracked!(inline_in_all_cgus, Some(true));
734     tracked!(inline_mir, Some(true));
735     tracked!(inline_mir_hint_threshold, Some(123));
736     tracked!(inline_mir_threshold, Some(123));
737     tracked!(instrument_coverage, Some(InstrumentCoverage::All));
738     tracked!(instrument_mcount, true);
739     tracked!(link_only, true);
740     tracked!(llvm_plugins, vec![String::from("plugin_name")]);
741     tracked!(location_detail, LocationDetail { file: true, line: false, column: false });
742     tracked!(merge_functions, Some(MergeFunctions::Disabled));
743     tracked!(mir_emit_retag, true);
744     tracked!(mir_opt_level, Some(4));
745     tracked!(move_size_limit, Some(4096));
746     tracked!(mutable_noalias, Some(true));
747     tracked!(new_llvm_pass_manager, Some(true));
748     tracked!(no_generate_arange_section, true);
749     tracked!(no_link, true);
750     tracked!(no_unique_section_names, true);
751     tracked!(no_profiler_runtime, true);
752     tracked!(osx_rpath_install_name, true);
753     tracked!(panic_abort_tests, true);
754     tracked!(panic_in_drop, PanicStrategy::Abort);
755     tracked!(partially_uninit_const_threshold, Some(123));
756     tracked!(pick_stable_methods_before_any_unstable, false);
757     tracked!(plt, Some(true));
758     tracked!(polonius, true);
759     tracked!(precise_enum_drop_elaboration, false);
760     tracked!(print_fuel, Some("abc".to_string()));
761     tracked!(profile, true);
762     tracked!(profile_emit, Some(PathBuf::from("abc")));
763     tracked!(profiler_runtime, "abc".to_string());
764     tracked!(profile_sample_use, Some(PathBuf::from("abc")));
765     tracked!(relax_elf_relocations, Some(true));
766     tracked!(relro_level, Some(RelroLevel::Full));
767     tracked!(remap_cwd_prefix, Some(PathBuf::from("abc")));
768     tracked!(report_delayed_bugs, true);
769     tracked!(sanitizer, SanitizerSet::ADDRESS);
770     tracked!(sanitizer_memory_track_origins, 2);
771     tracked!(sanitizer_recover, SanitizerSet::ADDRESS);
772     tracked!(saturating_float_casts, Some(true));
773     tracked!(share_generics, Some(true));
774     tracked!(show_span, Some(String::from("abc")));
775     tracked!(simulate_remapped_rust_src_base, Some(PathBuf::from("/rustc/abc")));
776     tracked!(src_hash_algorithm, Some(SourceFileHashAlgorithm::Sha1));
777     tracked!(stack_protector, StackProtector::All);
778     tracked!(symbol_mangling_version, Some(SymbolManglingVersion::V0));
779     tracked!(teach, true);
780     tracked!(thinlto, Some(true));
781     tracked!(thir_unsafeck, true);
782     tracked!(tls_model, Some(TlsModel::GeneralDynamic));
783     tracked!(trap_unreachable, Some(false));
784     tracked!(treat_err_as_bug, NonZeroUsize::new(1));
785     tracked!(tune_cpu, Some(String::from("abc")));
786     tracked!(unleash_the_miri_inside_of_you, true);
787     tracked!(use_ctors_section, Some(true));
788     tracked!(verify_llvm_ir, true);
789     tracked!(wasi_exec_model, Some(WasiExecModel::Reactor));
790
791     macro_rules! tracked_no_crate_hash {
792         ($name: ident, $non_default_value: expr) => {
793             opts = reference.clone();
794             assert_ne!(opts.debugging_opts.$name, $non_default_value);
795             opts.debugging_opts.$name = $non_default_value;
796             assert_non_crate_hash_different(&reference, &opts);
797         };
798     }
799     tracked_no_crate_hash!(no_codegen, true);
800 }
801
802 #[test]
803 fn test_edition_parsing() {
804     // test default edition
805     let options = Options::default();
806     assert!(options.edition == DEFAULT_EDITION);
807
808     let matches = optgroups().parse(&["--edition=2018".to_string()]).unwrap();
809     let (sessopts, _) = build_session_options_and_crate_config(matches);
810     assert!(sessopts.edition == Edition::Edition2018)
811 }