]> git.lizzy.rs Git - rust.git/blob - src/librustc_interface/tests.rs
Add hooks for Miri panic unwinding
[rust.git] / src / librustc_interface / tests.rs
1 extern crate getopts;
2
3 use crate::interface::parse_cfgspecs;
4
5 use rustc::lint;
6 use rustc::middle::cstore;
7 use rustc::session::config::{build_configuration, build_session_options, to_crate_config};
8 use rustc::session::config::{LtoCli, LinkerPluginLto, SwitchWithOptPath, ExternEntry};
9 use rustc::session::config::{Externs, OutputType, OutputTypes, SymbolManglingVersion};
10 use rustc::session::config::{rustc_optgroups, Options, ErrorOutputType, Passes};
11 use rustc::session::{build_session, Session};
12 use rustc::session::search_paths::SearchPath;
13 use std::collections::{BTreeMap, BTreeSet};
14 use std::iter::FromIterator;
15 use std::path::PathBuf;
16 use rustc_target::spec::{MergeFunctions, PanicStrategy, RelroLevel};
17 use syntax::symbol::sym;
18 use syntax::edition::{Edition, DEFAULT_EDITION};
19 use syntax;
20 use syntax_expand::config::process_configure_mod;
21 use rustc_data_structures::fx::FxHashSet;
22 use rustc_errors::{ColorConfig, emitter::HumanReadableErrorType, registry};
23
24 type CfgSpecs = FxHashSet<(String, Option<String>)>;
25
26 fn build_session_options_and_crate_config(matches: getopts::Matches) -> (Options, CfgSpecs) {
27     let sessopts = build_session_options(&matches);
28     let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
29     (sessopts, cfg)
30 }
31
32 fn mk_session(matches: getopts::Matches) -> (Session, CfgSpecs) {
33     let registry = registry::Registry::new(&[]);
34     let (sessopts, cfg) = build_session_options_and_crate_config(matches);
35     let sess = build_session(sessopts, None, registry, process_configure_mod);
36     (sess, cfg)
37 }
38
39 fn new_public_extern_entry<S, I>(locations: I) -> ExternEntry
40 where
41     S: Into<String>,
42     I: IntoIterator<Item = Option<S>>,
43 {
44     let locations: BTreeSet<_> = locations.into_iter().map(|o| o.map(|s| s.into()))
45         .collect();
46
47     ExternEntry {
48         locations,
49         is_private_dep: false
50     }
51 }
52
53 fn optgroups() -> getopts::Options {
54     let mut opts = getopts::Options::new();
55     for group in rustc_optgroups() {
56         (group.apply)(&mut opts);
57     }
58     return opts;
59 }
60
61 fn mk_map<K: Ord, V>(entries: Vec<(K, V)>) -> BTreeMap<K, V> {
62     BTreeMap::from_iter(entries.into_iter())
63 }
64
65 // When the user supplies --test we should implicitly supply --cfg test
66 #[test]
67 fn test_switch_implies_cfg_test() {
68     syntax::with_default_globals(|| {
69         let matches = optgroups().parse(&["--test".to_string()]).unwrap();
70         let (sess, cfg) = mk_session(matches);
71         let cfg = build_configuration(&sess, to_crate_config(cfg));
72         assert!(cfg.contains(&(sym::test, None)));
73     });
74 }
75
76 // When the user supplies --test and --cfg test, don't implicitly add another --cfg test
77 #[test]
78 fn test_switch_implies_cfg_test_unless_cfg_test() {
79     syntax::with_default_globals(|| {
80         let matches = optgroups().parse(&["--test".to_string(), "--cfg=test".to_string()]).unwrap();
81         let (sess, cfg) = mk_session(matches);
82         let cfg = build_configuration(&sess, to_crate_config(cfg));
83         let mut test_items = cfg.iter().filter(|&&(name, _)| name == sym::test);
84         assert!(test_items.next().is_some());
85         assert!(test_items.next().is_none());
86     });
87 }
88
89 #[test]
90 fn test_can_print_warnings() {
91     syntax::with_default_globals(|| {
92         let matches = optgroups().parse(&["-Awarnings".to_string()]).unwrap();
93         let (sess, _) = mk_session(matches);
94         assert!(!sess.diagnostic().can_emit_warnings());
95     });
96
97     syntax::with_default_globals(|| {
98         let matches = optgroups()
99             .parse(&["-Awarnings".to_string(), "-Dwarnings".to_string()])
100             .unwrap();
101         let (sess, _) = mk_session(matches);
102         assert!(sess.diagnostic().can_emit_warnings());
103     });
104
105     syntax::with_default_globals(|| {
106         let matches = optgroups().parse(&["-Adead_code".to_string()]).unwrap();
107         let (sess, _) = mk_session(matches);
108         assert!(sess.diagnostic().can_emit_warnings());
109     });
110 }
111
112 #[test]
113 fn test_output_types_tracking_hash_different_paths() {
114     let mut v1 = Options::default();
115     let mut v2 = Options::default();
116     let mut v3 = Options::default();
117
118     v1.output_types =
119         OutputTypes::new(&[(OutputType::Exe, Some(PathBuf::from("./some/thing")))]);
120     v2.output_types =
121         OutputTypes::new(&[(OutputType::Exe, Some(PathBuf::from("/some/thing")))]);
122     v3.output_types = OutputTypes::new(&[(OutputType::Exe, None)]);
123
124     assert!(v1.dep_tracking_hash() != v2.dep_tracking_hash());
125     assert!(v1.dep_tracking_hash() != v3.dep_tracking_hash());
126     assert!(v2.dep_tracking_hash() != v3.dep_tracking_hash());
127
128     // Check clone
129     assert_eq!(v1.dep_tracking_hash(), v1.clone().dep_tracking_hash());
130     assert_eq!(v2.dep_tracking_hash(), v2.clone().dep_tracking_hash());
131     assert_eq!(v3.dep_tracking_hash(), v3.clone().dep_tracking_hash());
132 }
133
134 #[test]
135 fn test_output_types_tracking_hash_different_construction_order() {
136     let mut v1 = Options::default();
137     let mut v2 = Options::default();
138
139     v1.output_types = OutputTypes::new(&[
140         (OutputType::Exe, Some(PathBuf::from("./some/thing"))),
141         (OutputType::Bitcode, Some(PathBuf::from("./some/thing.bc"))),
142     ]);
143
144     v2.output_types = OutputTypes::new(&[
145         (OutputType::Bitcode, Some(PathBuf::from("./some/thing.bc"))),
146         (OutputType::Exe, Some(PathBuf::from("./some/thing"))),
147     ]);
148
149     assert_eq!(v1.dep_tracking_hash(), v2.dep_tracking_hash());
150
151     // Check clone
152     assert_eq!(v1.dep_tracking_hash(), v1.clone().dep_tracking_hash());
153 }
154
155 #[test]
156 fn test_externs_tracking_hash_different_construction_order() {
157     let mut v1 = Options::default();
158     let mut v2 = Options::default();
159     let mut v3 = Options::default();
160
161     v1.externs = Externs::new(mk_map(vec![
162         (
163             String::from("a"),
164             new_public_extern_entry(vec![Some("b"), Some("c")])
165         ),
166         (
167             String::from("d"),
168             new_public_extern_entry(vec![Some("e"), Some("f")])
169         ),
170     ]));
171
172     v2.externs = Externs::new(mk_map(vec![
173         (
174             String::from("d"),
175             new_public_extern_entry(vec![Some("e"), Some("f")])
176         ),
177         (
178             String::from("a"),
179             new_public_extern_entry(vec![Some("b"), Some("c")])
180         ),
181     ]));
182
183     v3.externs = Externs::new(mk_map(vec![
184         (
185             String::from("a"),
186             new_public_extern_entry(vec![Some("b"), Some("c")])
187         ),
188         (
189             String::from("d"),
190             new_public_extern_entry(vec![Some("f"), Some("e")])
191         ),
192     ]));
193
194     assert_eq!(v1.dep_tracking_hash(), v2.dep_tracking_hash());
195     assert_eq!(v1.dep_tracking_hash(), v3.dep_tracking_hash());
196     assert_eq!(v2.dep_tracking_hash(), v3.dep_tracking_hash());
197
198     // Check clone
199     assert_eq!(v1.dep_tracking_hash(), v1.clone().dep_tracking_hash());
200     assert_eq!(v2.dep_tracking_hash(), v2.clone().dep_tracking_hash());
201     assert_eq!(v3.dep_tracking_hash(), v3.clone().dep_tracking_hash());
202 }
203
204 #[test]
205 fn test_lints_tracking_hash_different_values() {
206     let mut v1 = Options::default();
207     let mut v2 = Options::default();
208     let mut v3 = Options::default();
209
210     v1.lint_opts = vec![
211         (String::from("a"), lint::Allow),
212         (String::from("b"), lint::Warn),
213         (String::from("c"), lint::Deny),
214         (String::from("d"), lint::Forbid),
215     ];
216
217     v2.lint_opts = vec![
218         (String::from("a"), lint::Allow),
219         (String::from("b"), lint::Warn),
220         (String::from("X"), lint::Deny),
221         (String::from("d"), lint::Forbid),
222     ];
223
224     v3.lint_opts = vec![
225         (String::from("a"), lint::Allow),
226         (String::from("b"), lint::Warn),
227         (String::from("c"), lint::Forbid),
228         (String::from("d"), lint::Deny),
229     ];
230
231     assert!(v1.dep_tracking_hash() != v2.dep_tracking_hash());
232     assert!(v1.dep_tracking_hash() != v3.dep_tracking_hash());
233     assert!(v2.dep_tracking_hash() != v3.dep_tracking_hash());
234
235     // Check clone
236     assert_eq!(v1.dep_tracking_hash(), v1.clone().dep_tracking_hash());
237     assert_eq!(v2.dep_tracking_hash(), v2.clone().dep_tracking_hash());
238     assert_eq!(v3.dep_tracking_hash(), v3.clone().dep_tracking_hash());
239 }
240
241 #[test]
242 fn test_lints_tracking_hash_different_construction_order() {
243     let mut v1 = Options::default();
244     let mut v2 = Options::default();
245
246     v1.lint_opts = vec![
247         (String::from("a"), lint::Allow),
248         (String::from("b"), lint::Warn),
249         (String::from("c"), lint::Deny),
250         (String::from("d"), lint::Forbid),
251     ];
252
253     v2.lint_opts = vec![
254         (String::from("a"), lint::Allow),
255         (String::from("c"), lint::Deny),
256         (String::from("b"), lint::Warn),
257         (String::from("d"), lint::Forbid),
258     ];
259
260     assert_eq!(v1.dep_tracking_hash(), v2.dep_tracking_hash());
261
262     // Check clone
263     assert_eq!(v1.dep_tracking_hash(), v1.clone().dep_tracking_hash());
264     assert_eq!(v2.dep_tracking_hash(), v2.clone().dep_tracking_hash());
265 }
266
267 #[test]
268 fn test_search_paths_tracking_hash_different_order() {
269     let mut v1 = Options::default();
270     let mut v2 = Options::default();
271     let mut v3 = Options::default();
272     let mut v4 = Options::default();
273
274     const JSON: ErrorOutputType = ErrorOutputType::Json {
275         pretty: false,
276         json_rendered: HumanReadableErrorType::Default(ColorConfig::Never),
277     };
278
279     // Reference
280     v1.search_paths
281         .push(SearchPath::from_cli_opt("native=abc", JSON));
282     v1.search_paths
283         .push(SearchPath::from_cli_opt("crate=def", JSON));
284     v1.search_paths
285         .push(SearchPath::from_cli_opt("dependency=ghi", JSON));
286     v1.search_paths
287         .push(SearchPath::from_cli_opt("framework=jkl", JSON));
288     v1.search_paths
289         .push(SearchPath::from_cli_opt("all=mno", JSON));
290
291     v2.search_paths
292         .push(SearchPath::from_cli_opt("native=abc", JSON));
293     v2.search_paths
294         .push(SearchPath::from_cli_opt("dependency=ghi", JSON));
295     v2.search_paths
296         .push(SearchPath::from_cli_opt("crate=def", JSON));
297     v2.search_paths
298         .push(SearchPath::from_cli_opt("framework=jkl", JSON));
299     v2.search_paths
300         .push(SearchPath::from_cli_opt("all=mno", JSON));
301
302     v3.search_paths
303         .push(SearchPath::from_cli_opt("crate=def", JSON));
304     v3.search_paths
305         .push(SearchPath::from_cli_opt("framework=jkl", JSON));
306     v3.search_paths
307         .push(SearchPath::from_cli_opt("native=abc", JSON));
308     v3.search_paths
309         .push(SearchPath::from_cli_opt("dependency=ghi", JSON));
310     v3.search_paths
311         .push(SearchPath::from_cli_opt("all=mno", JSON));
312
313     v4.search_paths
314         .push(SearchPath::from_cli_opt("all=mno", JSON));
315     v4.search_paths
316         .push(SearchPath::from_cli_opt("native=abc", JSON));
317     v4.search_paths
318         .push(SearchPath::from_cli_opt("crate=def", JSON));
319     v4.search_paths
320         .push(SearchPath::from_cli_opt("dependency=ghi", JSON));
321     v4.search_paths
322         .push(SearchPath::from_cli_opt("framework=jkl", JSON));
323
324     assert!(v1.dep_tracking_hash() == v2.dep_tracking_hash());
325     assert!(v1.dep_tracking_hash() == v3.dep_tracking_hash());
326     assert!(v1.dep_tracking_hash() == v4.dep_tracking_hash());
327
328     // Check clone
329     assert_eq!(v1.dep_tracking_hash(), v1.clone().dep_tracking_hash());
330     assert_eq!(v2.dep_tracking_hash(), v2.clone().dep_tracking_hash());
331     assert_eq!(v3.dep_tracking_hash(), v3.clone().dep_tracking_hash());
332     assert_eq!(v4.dep_tracking_hash(), v4.clone().dep_tracking_hash());
333 }
334
335 #[test]
336 fn test_native_libs_tracking_hash_different_values() {
337     let mut v1 = Options::default();
338     let mut v2 = Options::default();
339     let mut v3 = Options::default();
340     let mut v4 = Options::default();
341
342     // Reference
343     v1.libs = vec![
344         (String::from("a"), None, Some(cstore::NativeStatic)),
345         (String::from("b"), None, Some(cstore::NativeFramework)),
346         (String::from("c"), None, Some(cstore::NativeUnknown)),
347     ];
348
349     // Change label
350     v2.libs = vec![
351         (String::from("a"), None, Some(cstore::NativeStatic)),
352         (String::from("X"), None, Some(cstore::NativeFramework)),
353         (String::from("c"), None, Some(cstore::NativeUnknown)),
354     ];
355
356     // Change kind
357     v3.libs = vec![
358         (String::from("a"), None, Some(cstore::NativeStatic)),
359         (String::from("b"), None, Some(cstore::NativeStatic)),
360         (String::from("c"), None, Some(cstore::NativeUnknown)),
361     ];
362
363     // Change new-name
364     v4.libs = vec![
365         (String::from("a"), None, Some(cstore::NativeStatic)),
366         (
367             String::from("b"),
368             Some(String::from("X")),
369             Some(cstore::NativeFramework),
370         ),
371         (String::from("c"), None, Some(cstore::NativeUnknown)),
372     ];
373
374     assert!(v1.dep_tracking_hash() != v2.dep_tracking_hash());
375     assert!(v1.dep_tracking_hash() != v3.dep_tracking_hash());
376     assert!(v1.dep_tracking_hash() != v4.dep_tracking_hash());
377
378     // Check clone
379     assert_eq!(v1.dep_tracking_hash(), v1.clone().dep_tracking_hash());
380     assert_eq!(v2.dep_tracking_hash(), v2.clone().dep_tracking_hash());
381     assert_eq!(v3.dep_tracking_hash(), v3.clone().dep_tracking_hash());
382     assert_eq!(v4.dep_tracking_hash(), v4.clone().dep_tracking_hash());
383 }
384
385 #[test]
386 fn test_native_libs_tracking_hash_different_order() {
387     let mut v1 = Options::default();
388     let mut v2 = Options::default();
389     let mut v3 = Options::default();
390
391     // Reference
392     v1.libs = vec![
393         (String::from("a"), None, Some(cstore::NativeStatic)),
394         (String::from("b"), None, Some(cstore::NativeFramework)),
395         (String::from("c"), None, Some(cstore::NativeUnknown)),
396     ];
397
398     v2.libs = vec![
399         (String::from("b"), None, Some(cstore::NativeFramework)),
400         (String::from("a"), None, Some(cstore::NativeStatic)),
401         (String::from("c"), None, Some(cstore::NativeUnknown)),
402     ];
403
404     v3.libs = vec![
405         (String::from("c"), None, Some(cstore::NativeUnknown)),
406         (String::from("a"), None, Some(cstore::NativeStatic)),
407         (String::from("b"), None, Some(cstore::NativeFramework)),
408     ];
409
410     assert!(v1.dep_tracking_hash() == v2.dep_tracking_hash());
411     assert!(v1.dep_tracking_hash() == v3.dep_tracking_hash());
412     assert!(v2.dep_tracking_hash() == v3.dep_tracking_hash());
413
414     // Check clone
415     assert_eq!(v1.dep_tracking_hash(), v1.clone().dep_tracking_hash());
416     assert_eq!(v2.dep_tracking_hash(), v2.clone().dep_tracking_hash());
417     assert_eq!(v3.dep_tracking_hash(), v3.clone().dep_tracking_hash());
418 }
419
420 #[test]
421 fn test_codegen_options_tracking_hash() {
422     let reference = Options::default();
423     let mut opts = Options::default();
424
425     // Make sure the changing an [UNTRACKED] option leaves the hash unchanged
426     opts.cg.ar = Some(String::from("abc"));
427     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
428
429     opts.cg.linker = Some(PathBuf::from("linker"));
430     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
431
432     opts.cg.link_args = Some(vec![String::from("abc"), String::from("def")]);
433     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
434
435     opts.cg.link_dead_code = true;
436     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
437
438     opts.cg.rpath = true;
439     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
440
441     opts.cg.extra_filename = String::from("extra-filename");
442     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
443
444     opts.cg.codegen_units = Some(42);
445     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
446
447     opts.cg.remark = Passes::Some(vec![String::from("pass1"), String::from("pass2")]);
448     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
449
450     opts.cg.save_temps = true;
451     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
452
453     opts.cg.incremental = Some(String::from("abc"));
454     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
455
456     // Make sure changing a [TRACKED] option changes the hash
457     opts = reference.clone();
458     opts.cg.lto = LtoCli::Fat;
459     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
460
461     opts = reference.clone();
462     opts.cg.target_cpu = Some(String::from("abc"));
463     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
464
465     opts = reference.clone();
466     opts.cg.target_feature = String::from("all the features, all of them");
467     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
468
469     opts = reference.clone();
470     opts.cg.passes = vec![String::from("1"), String::from("2")];
471     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
472
473     opts = reference.clone();
474     opts.cg.llvm_args = vec![String::from("1"), String::from("2")];
475     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
476
477     opts = reference.clone();
478     opts.cg.overflow_checks = Some(true);
479     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
480
481     opts = reference.clone();
482     opts.cg.no_prepopulate_passes = true;
483     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
484
485     opts = reference.clone();
486     opts.cg.no_vectorize_loops = true;
487     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
488
489     opts = reference.clone();
490     opts.cg.no_vectorize_slp = true;
491     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
492
493     opts = reference.clone();
494     opts.cg.soft_float = true;
495     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
496
497     opts = reference.clone();
498     opts.cg.prefer_dynamic = true;
499     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
500
501     opts = reference.clone();
502     opts.cg.no_integrated_as = true;
503     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
504
505     opts = reference.clone();
506     opts.cg.no_redzone = Some(true);
507     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
508
509     opts = reference.clone();
510     opts.cg.relocation_model = Some(String::from("relocation model"));
511     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
512
513     opts = reference.clone();
514     opts.cg.code_model = Some(String::from("code model"));
515     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
516
517     opts = reference.clone();
518     opts.debugging_opts.tls_model = Some(String::from("tls model"));
519     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
520
521     opts = reference.clone();
522     opts.cg.profile_generate = SwitchWithOptPath::Enabled(None);
523     assert_ne!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
524
525     opts = reference.clone();
526     opts.cg.profile_use = Some(PathBuf::from("abc"));
527     assert_ne!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
528
529     opts = reference.clone();
530     opts.cg.metadata = vec![String::from("A"), String::from("B")];
531     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
532
533     opts = reference.clone();
534     opts.cg.debuginfo = Some(0xdeadbeef);
535     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
536
537     opts = reference.clone();
538     opts.cg.debuginfo = Some(0xba5eba11);
539     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
540
541     opts = reference.clone();
542     opts.cg.force_frame_pointers = Some(false);
543     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
544
545     opts = reference.clone();
546     opts.cg.debug_assertions = Some(true);
547     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
548
549     opts = reference.clone();
550     opts.cg.inline_threshold = Some(0xf007ba11);
551     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
552
553     opts = reference.clone();
554     opts.cg.panic = Some(PanicStrategy::Abort);
555     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
556
557     opts = reference.clone();
558     opts.cg.linker_plugin_lto = LinkerPluginLto::LinkerPluginAuto;
559     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
560 }
561
562 #[test]
563 fn test_debugging_options_tracking_hash() {
564     let reference = Options::default();
565     let mut opts = Options::default();
566
567     // Make sure the changing an [UNTRACKED] option leaves the hash unchanged
568     opts.debugging_opts.verbose = true;
569     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
570     opts.debugging_opts.time_passes = true;
571     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
572     opts.debugging_opts.time_llvm_passes = true;
573     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
574     opts.debugging_opts.input_stats = true;
575     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
576     opts.debugging_opts.borrowck_stats = true;
577     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
578     opts.debugging_opts.meta_stats = true;
579     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
580     opts.debugging_opts.print_link_args = true;
581     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
582     opts.debugging_opts.print_llvm_passes = true;
583     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
584     opts.debugging_opts.ast_json = true;
585     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
586     opts.debugging_opts.ast_json_noexpand = true;
587     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
588     opts.debugging_opts.ls = true;
589     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
590     opts.debugging_opts.save_analysis = true;
591     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
592     opts.debugging_opts.print_region_graph = true;
593     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
594     opts.debugging_opts.parse_only = true;
595     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
596     opts.debugging_opts.incremental = Some(String::from("abc"));
597     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
598     opts.debugging_opts.dump_dep_graph = true;
599     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
600     opts.debugging_opts.query_dep_graph = true;
601     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
602     opts.debugging_opts.no_analysis = true;
603     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
604     opts.debugging_opts.unstable_options = true;
605     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
606     opts.debugging_opts.trace_macros = true;
607     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
608     opts.debugging_opts.keep_hygiene_data = true;
609     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
610     opts.debugging_opts.keep_ast = true;
611     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
612     opts.debugging_opts.print_mono_items = Some(String::from("abc"));
613     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
614     opts.debugging_opts.dump_mir = Some(String::from("abc"));
615     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
616     opts.debugging_opts.dump_mir_dir = String::from("abc");
617     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
618     opts.debugging_opts.dump_mir_graphviz = true;
619     assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
620
621     // Make sure changing a [TRACKED] option changes the hash
622     opts = reference.clone();
623     opts.debugging_opts.asm_comments = true;
624     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
625
626     opts = reference.clone();
627     opts.debugging_opts.verify_llvm_ir = true;
628     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
629
630     opts = reference.clone();
631     opts.debugging_opts.no_landing_pads = true;
632     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
633
634     opts = reference.clone();
635     opts.debugging_opts.fewer_names = true;
636     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
637
638     opts = reference.clone();
639     opts.debugging_opts.no_codegen = true;
640     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
641
642     opts = reference.clone();
643     opts.debugging_opts.treat_err_as_bug = Some(1);
644     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
645
646     opts = reference.clone();
647     opts.debugging_opts.report_delayed_bugs = true;
648     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
649
650     opts = reference.clone();
651     opts.debugging_opts.continue_parse_after_error = true;
652     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
653
654     opts = reference.clone();
655     opts.debugging_opts.extra_plugins = vec![String::from("plugin1"), String::from("plugin2")];
656     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
657
658     opts = reference.clone();
659     opts.debugging_opts.force_overflow_checks = Some(true);
660     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
661
662     opts = reference.clone();
663     opts.debugging_opts.show_span = Some(String::from("abc"));
664     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
665
666     opts = reference.clone();
667     opts.debugging_opts.mir_opt_level = 3;
668     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
669
670     opts = reference.clone();
671     opts.debugging_opts.relro_level = Some(RelroLevel::Full);
672     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
673
674     opts = reference.clone();
675     opts.debugging_opts.merge_functions = Some(MergeFunctions::Disabled);
676     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
677
678     opts = reference.clone();
679     opts.debugging_opts.allow_features = Some(vec![String::from("lang_items")]);
680     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
681
682     opts = reference.clone();
683     opts.debugging_opts.symbol_mangling_version = SymbolManglingVersion::V0;
684     assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
685 }
686
687 #[test]
688 fn test_edition_parsing() {
689     // test default edition
690     let options = Options::default();
691     assert!(options.edition == DEFAULT_EDITION);
692
693     let matches = optgroups()
694         .parse(&["--edition=2018".to_string()])
695         .unwrap();
696     let (sessopts, _) = build_session_options_and_crate_config(matches);
697     assert!(sessopts.edition == Edition::Edition2018)
698 }