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