- fn after_parsing(&mut self, compiler: &interface::Compiler) -> bool {
- let sess = compiler.session();
- let mut registry = rustc_plugin::registry::Registry::new(
- sess,
- compiler
- .parse()
- .expect(
- "at this compilation stage \
- the crate must be parsed",
- )
- .peek()
- .span,
- );
- registry.args_hidden = Some(Vec::new());
-
- let conf = clippy_lints::read_conf(®istry);
- clippy_lints::register_plugins(&mut registry, &conf);
-
- let rustc_plugin::registry::Registry {
- early_lint_passes,
- late_lint_passes,
- lint_groups,
- llvm_passes,
- attributes,
- ..
- } = registry;
- let mut ls = sess.lint_store.borrow_mut();
- for pass in early_lint_passes {
- ls.register_early_pass(Some(sess), true, false, pass);
- }
- for pass in late_lint_passes {
- ls.register_late_pass(Some(sess), true, false, false, pass);
+ fn config(&mut self, config: &mut interface::Config) {
+ let previous = config.register_lints.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.
+ if let Some(previous) = &previous {
+ (previous)(sess, lint_store);
+ }
+
+ 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, &conf);
+ clippy_lints::register_renamed(&mut lint_store);
+ }));
+
+ // FIXME: #4825; This is required, because Clippy lints that are based on MIR have to be
+ // run on the unoptimized MIR. On the other hand this results in some false negatives. If
+ // MIR passes can be enabled / disabled separately, we should figure out, what passes to
+ // use for Clippy.
+ config.opts.debugging_opts.mir_opt_level = 0;
+ }
+}
+
+#[allow(clippy::find_map, clippy::filter_map)]
+fn describe_lints() {
+ use lintlist::{Level, Lint, ALL_LINTS, LINT_LEVELS};
+ use std::collections::HashSet;
+
+ println!(
+ "
+Available lint options:
+ -W <foo> Warn about <foo>
+ -A <foo> Allow <foo>
+ -D <foo> Deny <foo>
+ -F <foo> Forbid <foo> (deny <foo> and all attempts to override)
+
+"
+ );
+
+ let lint_level = |lint: &Lint| {
+ LINT_LEVELS
+ .iter()
+ .find(|level_mapping| level_mapping.0 == lint.group)
+ .map(|(_, level)| match level {
+ Level::Allow => "allow",
+ Level::Warn => "warn",
+ Level::Deny => "deny",
+ })
+ .unwrap()
+ };
+
+ let mut lints: Vec<_> = ALL_LINTS.iter().collect();
+ // The sort doesn't case-fold but it's doubtful we care.
+ lints.sort_by_cached_key(|x: &&Lint| (lint_level(x), x.name));
+
+ let max_lint_name_len = lints
+ .iter()
+ .map(|lint| lint.name.len())
+ .map(|len| len + "clippy::".len())
+ .max()
+ .unwrap_or(0);
+
+ let padded = |x: &str| {
+ let mut s = " ".repeat(max_lint_name_len - x.chars().count());
+ s.push_str(x);
+ s
+ };
+
+ let scoped = |x: &str| format!("clippy::{}", x);
+
+ let lint_groups: HashSet<_> = lints.iter().map(|lint| lint.group).collect();
+
+ println!("Lint checks provided by clippy:\n");
+ println!(" {} {:7.7} meaning", padded("name"), "default");
+ println!(" {} {:7.7} -------", padded("----"), "-------");
+
+ let print_lints = |lints: &[&Lint]| {
+ for lint in lints {
+ let name = lint.name.replace("_", "-");
+ println!(
+ " {} {:7.7} {}",
+ padded(&scoped(&name)),
+ lint_level(lint),
+ lint.desc
+ );