]> git.lizzy.rs Git - rust.git/blob - src/driver.rs
resolved conflicts
[rust.git] / src / driver.rs
1 // error-pattern:yummy
2 #![feature(box_syntax)]
3 #![feature(rustc_private)]
4 #![feature(tool_lints)]
5 #![allow(unknown_lints, clippy::missing_docs_in_private_items)]
6
7 use rustc_driver::{self, driver::CompileController, Compilation};
8 use rustc_plugin;
9 use std::process::{exit, Command};
10
11 #[allow(clippy::print_stdout)]
12 fn show_version() {
13     println!(env!("CARGO_PKG_VERSION"));
14 }
15
16 pub fn main() {
17     exit(rustc_driver::run(move || {
18         use std::env;
19
20         if std::env::args().any(|a| a == "--version" || a == "-V") {
21             show_version();
22             exit(0);
23         }
24
25         let sys_root = option_env!("SYSROOT")
26             .map(String::from)
27             .or_else(|| std::env::var("SYSROOT").ok())
28             .or_else(|| {
29                 let home = option_env!("RUSTUP_HOME").or(option_env!("MULTIRUST_HOME"));
30                 let toolchain = option_env!("RUSTUP_TOOLCHAIN").or(option_env!("MULTIRUST_TOOLCHAIN"));
31                 home.and_then(|home| toolchain.map(|toolchain| format!("{}/toolchains/{}", home, toolchain)))
32             })
33             .or_else(|| {
34                 Command::new("rustc")
35                     .arg("--print")
36                     .arg("sysroot")
37                     .output()
38                     .ok()
39                     .and_then(|out| String::from_utf8(out.stdout).ok())
40                     .map(|s| s.trim().to_owned())
41             })
42             .expect("need to specify SYSROOT env var during clippy compilation, or use rustup or multirust");
43
44         // Setting RUSTC_WRAPPER causes Cargo to pass 'rustc' as the first argument.
45         // We're invoking the compiler programmatically, so we ignore this/
46         let mut orig_args: Vec<String> = env::args().collect();
47         if orig_args.len() <= 1 {
48             std::process::exit(1);
49         }
50         if orig_args[1] == "rustc" {
51             // we still want to be able to invoke it normally though
52             orig_args.remove(1);
53         }
54         // this conditional check for the --sysroot flag is there so users can call
55         // `clippy_driver` directly
56         // without having to pass --sysroot or anything
57         let mut args: Vec<String> = if orig_args.iter().any(|s| s == "--sysroot") {
58             orig_args.clone()
59         } else {
60             orig_args
61                 .clone()
62                 .into_iter()
63                 .chain(Some("--sysroot".to_owned()))
64                 .chain(Some(sys_root))
65                 .collect()
66         };
67
68         // this check ensures that dependencies are built but not linted and the final
69         // crate is
70         // linted but not built
71         let clippy_enabled = env::var("CLIPPY_TESTS").ok().map_or(false, |val| val == "true")
72             || orig_args.iter().any(|s| s == "--emit=dep-info,metadata");
73
74         if clippy_enabled {
75             args.extend_from_slice(&["--cfg".to_owned(), r#"feature="cargo-clippy""#.to_owned()]);
76             if let Ok(extra_args) = env::var("CLIPPY_ARGS") {
77                 args.extend(
78                     extra_args
79                         .split("__CLIPPY_HACKERY__")
80                         .filter(|s| !s.is_empty())
81                         .map(str::to_owned),
82                 );
83             }
84         }
85
86         let mut controller = CompileController::basic();
87         if clippy_enabled {
88             controller.after_parse.callback = Box::new(move |state| {
89                 let mut registry = rustc_plugin::registry::Registry::new(
90                     state.session,
91                     state
92                         .krate
93                         .as_ref()
94                         .expect(
95                             "at this compilation stage \
96                             the crate must be parsed",
97                         )
98                         .span,
99                 );
100                 registry.args_hidden = Some(Vec::new());
101
102                 let conf = clippy_lints::read_conf(&registry);
103                 clippy_lints::register_plugins(&mut registry, &conf);
104
105                 let rustc_plugin::registry::Registry {
106                     early_lint_passes,
107                     late_lint_passes,
108                     lint_groups,
109                     llvm_passes,
110                     attributes,
111                     ..
112                 } = registry;
113                 let sess = &state.session;
114                 let mut ls = sess.lint_store.borrow_mut();
115                 for pass in early_lint_passes {
116                     ls.register_early_pass(Some(sess), true, pass);
117                 }
118                 for pass in late_lint_passes {
119                     ls.register_late_pass(Some(sess), true, pass);
120                 }
121
122                 for (name, (to, deprecated_name)) in lint_groups {
123                     ls.register_group(Some(sess), true, name, deprecated_name, to);
124                 }
125                 clippy_lints::register_pre_expansion_lints(sess, &mut ls, &conf);
126
127                 sess.plugin_llvm_passes.borrow_mut().extend(llvm_passes);
128                 sess.plugin_attributes.borrow_mut().extend(attributes);
129             });
130         }
131         controller.compilation_done.stop = Compilation::Stop;
132
133         let args = args;
134         rustc_driver::run_compiler(&args, Box::new(controller), None, None)
135     }) as i32)
136 }