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