Skip to content

Commit

Permalink
Auto merge of #77671 - flip1995:lint_list_always_plugins, r=oli-obk,M…
Browse files Browse the repository at this point in the history
…anishearth

Always print lints from plugins, if they're available

Currently you can get a list of lints and lint groups by running `rustc
-Whelp`. This prints an additional line at the end:
```
Compiler plugins can provide additional lints and lint groups. To see a listing of these, re-run `rustc -W help` with a crate filename.
```

Clippy is such a "compiler plugin", that provides additional lints.
Running `clippy-driver -Whelp` (`rustc` wrapper) still only prints the
rustc lints with the above message at the end. But when running
`clippy-driver -Whelp main.rs`, where `main.rs` is any rust file, it
also prints Clippy lints. I don't think this is a good approach from a
UX perspective: Why is a random file necessary to print a help message?

This PR changes this behavior: Whenever a compiler callback
registers lints, it is assumed that these lints come from a plugin and
are printed without having to specify a Rust source file.

Fixes rust-lang/rust-clippy#6122

cc `@Manishearth` `@ebroto` for the Clippy changes.
  • Loading branch information
bors committed Nov 26, 2020
2 parents 65ecc48 + e54c060 commit 72da5a9
Show file tree
Hide file tree
Showing 6 changed files with 14 additions and 3,110 deletions.
16 changes: 10 additions & 6 deletions compiler/rustc_driver/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,11 +248,18 @@ fn run_compiler(
interface::run_compiler(config, |compiler| {
let sopts = &compiler.session().opts;
if sopts.describe_lints {
let lint_store = rustc_lint::new_lint_store(
let mut lint_store = rustc_lint::new_lint_store(
sopts.debugging_opts.no_interleave_lints,
compiler.session().unstable_options(),
);
describe_lints(compiler.session(), &lint_store, false);
let registered_lints =
if let Some(register_lints) = compiler.register_lints() {
register_lints(compiler.session(), &mut lint_store);
true
} else {
false
};
describe_lints(compiler.session(), &lint_store, registered_lints);
return;
}
let should_stop = RustcDefaultCalls::print_crate_info(
Expand Down Expand Up @@ -954,10 +961,7 @@ Available lint options:

match (loaded_plugins, plugin.len(), plugin_groups.len()) {
(false, 0, _) | (false, _, 0) => {
println!(
"Compiler plugins can provide additional lints and lint groups. To see a \
listing of these, re-run `rustc -W help` with a crate filename."
);
println!("Lint tools like Clippy can provide additional lints and lint groups.");
}
(false, ..) => panic!("didn't load lint plugins but got them anyway!"),
(true, 0, 0) => println!("This crate does not load any lint plugins or lint groups."),
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_interface/src/interface.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ impl Compiler {
pub fn output_file(&self) -> &Option<PathBuf> {
&self.output_file
}
pub fn register_lints(&self) -> &Option<Box<dyn Fn(&Session, &mut LintStore) + Send + Sync>> {
&self.register_lints
}
pub fn build_output_filenames(
&self,
sess: &Session,
Expand Down
15 changes: 1 addition & 14 deletions src/tools/clippy/clippy_dev/src/update_lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,20 +22,7 @@ pub fn run(update_mode: UpdateMode) {

let usable_lint_count = round_to_fifty(usable_lints.len());

let mut file_change = replace_region_in_file(
Path::new("src/lintlist/mod.rs"),
"begin lint list",
"end lint list",
false,
update_mode == UpdateMode::Change,
|| {
format!("vec!{:#?}", sorted_usable_lints)
.lines()
.map(ToString::to_string)
.collect::<Vec<_>>()
},
)
.changed;
let mut file_change = false;

file_change |= replace_region_in_file(
Path::new("README.md"),
Expand Down
121 changes: 0 additions & 121 deletions src/tools/clippy/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@

// FIXME: switch to something more ergonomic here, once available.
// (Currently there is no way to opt into sysroot crates without `extern crate`.)
extern crate rustc_data_structures;
extern crate rustc_driver;
extern crate rustc_errors;
extern crate rustc_interface;
Expand All @@ -26,8 +25,6 @@ use std::panic;
use std::path::{Path, PathBuf};
use std::process::{exit, Command};

mod lintlist;

/// If a command-line option matches `find_arg`, then apply the predicate `pred` on its value. If
/// true, then return it. The parameter is assumed to be either `--arg=value` or `--arg value`.
fn arg_value<'a, T: Deref<Target = str>>(
Expand Down Expand Up @@ -92,113 +89,6 @@ impl rustc_driver::Callbacks for ClippyCallbacks {
}
}

#[allow(clippy::find_map, clippy::filter_map)]
fn describe_lints() {
use lintlist::{Level, Lint, ALL_LINTS, LINT_LEVELS};
use rustc_data_structures::fx::FxHashSet;

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: FxHashSet<_> = 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
);
}
println!("\n");
};

print_lints(&lints);

let max_group_name_len = std::cmp::max(
"clippy::all".len(),
lint_groups
.iter()
.map(|group| group.len())
.map(|len| len + "clippy::".len())
.max()
.unwrap_or(0),
);

let padded_group = |x: &str| {
let mut s = " ".repeat(max_group_name_len - x.chars().count());
s.push_str(x);
s
};

println!("Lint groups provided by clippy:\n");
println!(" {} sub-lints", padded_group("name"));
println!(" {} ---------", padded_group("----"));
println!(" {} the set of all clippy lints", padded_group("clippy::all"));

let print_lint_groups = || {
for group in lint_groups {
let name = group.to_lowercase().replace("_", "-");
let desc = lints
.iter()
.filter(|&lint| lint.group == group)
.map(|lint| lint.name)
.map(|name| name.replace("_", "-"))
.collect::<Vec<String>>()
.join(", ");
println!(" {} {}", padded_group(&scoped(&name)), desc);
}
println!("\n");
};

print_lint_groups();
}

fn display_help() {
println!(
"\
Expand Down Expand Up @@ -379,17 +269,6 @@ pub fn main() {
exit(0);
}

let should_describe_lints = || {
let args: Vec<_> = env::args().collect();
args.windows(2)
.any(|args| args[1] == "help" && matches!(args[0].as_str(), "-W" | "-A" | "-D" | "-F"))
};

if !wrapper_mode && should_describe_lints() {
describe_lints();
exit(0);
}

// this conditional check for the --sysroot flag is there so users can call
// `clippy_driver` directly
// without having to pass --sysroot or anything
Expand Down
27 changes: 0 additions & 27 deletions src/tools/clippy/src/lintlist/lint.rs

This file was deleted.

Loading

0 comments on commit 72da5a9

Please sign in to comment.