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