Auto merge of #4588 - phansch:add_custom_ice_hook, r=Manishearth
Add custom ICE message that points to Clippy repo
changelog: Link to Clippy issue tracker in ICE messages
This utilizes https://github.com/rust-lang/rust/pull/60584 by setting
our own `panic_hook` and pointing to our own issue tracker instead of
the rustc issue tracker.
This also adds a new internal lint to test the ICE message.
**Potential downsides**
* This essentially copies rustc's `report_ice` function as
`report_clippy_ice`. I think that's how it's meant to be implemented, but
maybe @jonas-schievink could have a look as well =)
The downside of more-or-less copying this function is that we have to
maintain it as well now.
The original function can be found [here][original].
* `driver` now depends directly on `rustc` and `rustc_errors`
Closes #2734
[original]: 59367b074f/src/librustc_driver/lib.rs (L1185)
This commit is contained in:
commit
0e66a780ad
@ -40,6 +40,7 @@ semver = "0.9"
|
||||
rustc_tools_util = { version = "0.2.0", path = "rustc_tools_util"}
|
||||
git2 = { version = "0.10", optional = true }
|
||||
tempfile = { version = "3.1.0", optional = true }
|
||||
lazy_static = "1.0"
|
||||
|
||||
[dev-dependencies]
|
||||
cargo_metadata = "0.9.0"
|
||||
|
@ -963,6 +963,7 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
|
||||
let array_size_threshold = conf.array_size_threshold;
|
||||
store.register_late_pass(move || box large_stack_arrays::LargeStackArrays::new(array_size_threshold));
|
||||
store.register_early_pass(|| box as_conversions::AsConversions);
|
||||
store.register_early_pass(|| box utils::internal_lints::ProduceIce);
|
||||
|
||||
store.register_group(true, "clippy::restriction", Some("clippy_restriction"), vec![
|
||||
LintId::of(&arithmetic::FLOAT_ARITHMETIC),
|
||||
@ -1057,6 +1058,7 @@ pub fn register_plugins(store: &mut lint::LintStore, sess: &Session, conf: &Conf
|
||||
LintId::of(&utils::internal_lints::COMPILER_LINT_FUNCTIONS),
|
||||
LintId::of(&utils::internal_lints::LINT_WITHOUT_LINT_PASS),
|
||||
LintId::of(&utils::internal_lints::OUTER_EXPN_EXPN_DATA),
|
||||
LintId::of(&utils::internal_lints::PRODUCE_ICE),
|
||||
]);
|
||||
|
||||
store.register_group(true, "clippy::all", Some("clippy"), vec![
|
||||
|
@ -11,8 +11,10 @@
|
||||
use rustc::{declare_lint_pass, declare_tool_lint, impl_lint_pass};
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_errors::Applicability;
|
||||
use syntax::ast;
|
||||
use syntax::ast::{Crate as AstCrate, ItemKind, Name};
|
||||
use syntax::source_map::Span;
|
||||
use syntax::visit::FnKind;
|
||||
use syntax_pos::symbol::SymbolStr;
|
||||
|
||||
declare_clippy_lint! {
|
||||
@ -99,6 +101,24 @@
|
||||
"using `cx.outer_expn().expn_data()` instead of `cx.outer_expn_data()`"
|
||||
}
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// **What it does:** Not an actual lint. This lint is only meant for testing our customized internal compiler
|
||||
/// error message by calling `panic`.
|
||||
///
|
||||
/// **Why is this bad?** ICE in large quantities can damage your teeth
|
||||
///
|
||||
/// **Known problems:** None
|
||||
///
|
||||
/// **Example:**
|
||||
/// Bad:
|
||||
/// ```rust,ignore
|
||||
/// 🍦🍦🍦🍦🍦
|
||||
/// ```
|
||||
pub PRODUCE_ICE,
|
||||
internal,
|
||||
"this message should not appear anywhere as we ICE before and don't emit the lint"
|
||||
}
|
||||
|
||||
declare_lint_pass!(ClippyLintsInternal => [CLIPPY_LINTS_INTERNAL]);
|
||||
|
||||
impl EarlyLintPass for ClippyLintsInternal {
|
||||
@ -302,3 +322,22 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, expr: &'tcx hir::Expr) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
declare_lint_pass!(ProduceIce => [PRODUCE_ICE]);
|
||||
|
||||
impl EarlyLintPass for ProduceIce {
|
||||
fn check_fn(&mut self, _: &EarlyContext<'_>, fn_kind: FnKind<'_>, _: &ast::FnDecl, _: Span, _: ast::NodeId) {
|
||||
if is_trigger_fn(fn_kind) {
|
||||
panic!("Testing the ICE message");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_trigger_fn(fn_kind: FnKind<'_>) -> bool {
|
||||
match fn_kind {
|
||||
FnKind::ItemFn(ident, ..) | FnKind::Method(ident, ..) => {
|
||||
ident.name.as_str() == "it_looks_like_you_are_trying_to_kill_clippy"
|
||||
},
|
||||
FnKind::Closure(..) => false,
|
||||
}
|
||||
}
|
||||
|
@ -5,13 +5,21 @@
|
||||
// FIXME: switch to something more ergonomic here, once available.
|
||||
// (Currently there is no way to opt into sysroot crates without `extern crate`.)
|
||||
#[allow(unused_extern_crates)]
|
||||
extern crate rustc;
|
||||
#[allow(unused_extern_crates)]
|
||||
extern crate rustc_driver;
|
||||
#[allow(unused_extern_crates)]
|
||||
extern crate rustc_errors;
|
||||
#[allow(unused_extern_crates)]
|
||||
extern crate rustc_interface;
|
||||
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc_interface::interface;
|
||||
use rustc_tools_util::*;
|
||||
|
||||
use lazy_static::lazy_static;
|
||||
use std::borrow::Cow;
|
||||
use std::panic;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::process::{exit, Command};
|
||||
|
||||
@ -221,9 +229,64 @@ fn display_help() {
|
||||
);
|
||||
}
|
||||
|
||||
const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rust-clippy/issues/new";
|
||||
|
||||
lazy_static! {
|
||||
static ref ICE_HOOK: Box<dyn Fn(&panic::PanicInfo<'_>) + Sync + Send + 'static> = {
|
||||
let hook = panic::take_hook();
|
||||
panic::set_hook(Box::new(|info| report_clippy_ice(info, BUG_REPORT_URL)));
|
||||
hook
|
||||
};
|
||||
}
|
||||
|
||||
fn report_clippy_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str) {
|
||||
// Invoke our ICE handler, which prints the actual panic message and optionally a backtrace
|
||||
(*ICE_HOOK)(info);
|
||||
|
||||
// Separate the output with an empty line
|
||||
eprintln!();
|
||||
|
||||
let emitter = Box::new(rustc_errors::emitter::EmitterWriter::stderr(
|
||||
rustc_errors::ColorConfig::Auto,
|
||||
None,
|
||||
false,
|
||||
false,
|
||||
None,
|
||||
false,
|
||||
));
|
||||
let handler = rustc_errors::Handler::with_emitter(true, None, emitter);
|
||||
|
||||
// a .span_bug or .bug call has already printed what
|
||||
// it wants to print.
|
||||
if !info.payload().is::<rustc_errors::ExplicitBug>() {
|
||||
let d = rustc_errors::Diagnostic::new(rustc_errors::Level::Bug, "unexpected panic");
|
||||
handler.emit_diagnostic(&d);
|
||||
handler.abort_if_errors_and_should_abort();
|
||||
}
|
||||
|
||||
let version_info = rustc_tools_util::get_version_info!();
|
||||
|
||||
let xs: Vec<Cow<'static, str>> = vec![
|
||||
"the compiler unexpectedly panicked. this is a bug.".into(),
|
||||
format!("we would appreciate a bug report: {}", bug_report_url).into(),
|
||||
format!("Clippy version: {}", version_info).into(),
|
||||
];
|
||||
|
||||
for note in &xs {
|
||||
handler.note_without_error(¬e);
|
||||
}
|
||||
|
||||
// If backtraces are enabled, also print the query stack
|
||||
let backtrace = std::env::var_os("RUST_BACKTRACE").map_or(false, |x| &x != "0");
|
||||
|
||||
if backtrace {
|
||||
TyCtxt::try_print_query_stack(&handler);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() {
|
||||
rustc_driver::init_rustc_env_logger();
|
||||
rustc_driver::install_ice_hook();
|
||||
lazy_static::initialize(&ICE_HOOK);
|
||||
exit(
|
||||
rustc_driver::catch_fatal_errors(move || {
|
||||
use std::env;
|
||||
|
9
tests/ui/custom_ice_message.rs
Normal file
9
tests/ui/custom_ice_message.rs
Normal file
@ -0,0 +1,9 @@
|
||||
// rustc-env:RUST_BACKTRACE=0
|
||||
// normalize-stderr-test: "Clippy version: .*" -> "Clippy version: foo"
|
||||
// normalize-stderr-test: "internal_lints.rs:\d*:\d*" -> "internal_lints.rs"
|
||||
|
||||
#![deny(clippy::internal)]
|
||||
|
||||
fn it_looks_like_you_are_trying_to_kill_clippy() {}
|
||||
|
||||
fn main() {}
|
11
tests/ui/custom_ice_message.stderr
Normal file
11
tests/ui/custom_ice_message.stderr
Normal file
@ -0,0 +1,11 @@
|
||||
thread 'rustc' panicked at 'Testing the ICE message', clippy_lints/src/utils/internal_lints.rs
|
||||
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
|
||||
|
||||
error: internal compiler error: unexpected panic
|
||||
|
||||
note: the compiler unexpectedly panicked. this is a bug.
|
||||
|
||||
note: we would appreciate a bug report: https://github.com/rust-lang/rust-clippy/issues/new
|
||||
|
||||
note: Clippy version: foo
|
||||
|
Loading…
Reference in New Issue
Block a user