about summary refs log tree commit diff
path: root/src/driver.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/driver.rs')
-rw-r--r--src/driver.rs54
1 files changed, 46 insertions, 8 deletions
diff --git a/src/driver.rs b/src/driver.rs
index 94af21568ee..30272c9b800 100644
--- a/src/driver.rs
+++ b/src/driver.rs
@@ -11,8 +11,12 @@
 extern crate rustc_driver;
 extern crate rustc_errors;
 extern crate rustc_interface;
+extern crate rustc_session;
+extern crate rustc_span;
 
 use rustc_interface::interface;
+use rustc_session::Session;
+use rustc_span::symbol::Symbol;
 use rustc_tools_util::VersionInfo;
 
 use std::borrow::Cow;
@@ -59,13 +63,44 @@ fn test_arg_value() {
     assert_eq!(arg_value(args, "--foo", |_| true), None);
 }
 
+fn track_clippy_args(sess: &Session, args_env_var: &Option<String>) {
+    sess.parse_sess.env_depinfo.borrow_mut().insert((
+        Symbol::intern("CLIPPY_ARGS"),
+        args_env_var.as_deref().map(Symbol::intern),
+    ));
+}
+
 struct DefaultCallbacks;
 impl rustc_driver::Callbacks for DefaultCallbacks {}
 
-struct ClippyCallbacks;
+/// This is different from `DefaultCallbacks` that it will inform Cargo to track the value of
+/// `CLIPPY_ARGS` environment variable.
+struct RustcCallbacks {
+    clippy_args_var: Option<String>,
+}
+
+impl rustc_driver::Callbacks for RustcCallbacks {
+    fn config(&mut self, config: &mut interface::Config) {
+        let previous = config.register_lints.take();
+        let clippy_args_var = self.clippy_args_var.take();
+        config.register_lints = Some(Box::new(move |sess, lint_store| {
+            if let Some(ref previous) = previous {
+                (previous)(sess, lint_store);
+            }
+
+            track_clippy_args(sess, &clippy_args_var);
+        }));
+    }
+}
+
+struct ClippyCallbacks {
+    clippy_args_var: Option<String>,
+}
+
 impl rustc_driver::Callbacks for ClippyCallbacks {
     fn config(&mut self, config: &mut interface::Config) {
         let previous = config.register_lints.take();
+        let clippy_args_var = self.clippy_args_var.take();
         config.register_lints = Some(Box::new(move |sess, mut lint_store| {
             // technically we're ~guaranteed that this is none but might as well call anything that
             // is there already. Certainly it can't hurt.
@@ -73,6 +108,8 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
                 (previous)(sess, lint_store);
             }
 
+            track_clippy_args(sess, &clippy_args_var);
+
             let conf = clippy_lints::read_conf(&[], &sess);
             clippy_lints::register_plugins(&mut lint_store, &sess, &conf);
             clippy_lints::register_pre_expansion_lints(&mut lint_store);
@@ -277,7 +314,9 @@ pub fn main() {
         };
 
         let mut no_deps = false;
-        let clippy_args = env::var("CLIPPY_ARGS")
+        let clippy_args_var = env::var("CLIPPY_ARGS").ok();
+        let clippy_args = clippy_args_var
+            .as_deref()
             .unwrap_or_default()
             .split("__CLIPPY_HACKERY__")
             .filter_map(|s| match s {
@@ -305,11 +344,10 @@ pub fn main() {
             args.extend(clippy_args);
         }
 
-        let mut clippy = ClippyCallbacks;
-        let mut default = DefaultCallbacks;
-        let callbacks: &mut (dyn rustc_driver::Callbacks + Send) =
-            if clippy_enabled { &mut clippy } else { &mut default };
-
-        rustc_driver::RunCompiler::new(&args, callbacks).run()
+        if clippy_enabled {
+            rustc_driver::RunCompiler::new(&args, &mut ClippyCallbacks { clippy_args_var }).run()
+        } else {
+            rustc_driver::RunCompiler::new(&args, &mut RustcCallbacks { clippy_args_var }).run()
+        }
     }))
 }