From 9d3719bcfa45c977dcfd12a2d5f188652f56bdaf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= <john.kare.alsaker@gmail.com> Date: Thu, 1 Feb 2018 18:10:56 +0100 Subject: [PATCH] Do not run the default panic hook inside procedural macros. Fixes #47812 --- src/Cargo.lock | 2 ++ src/libproc_macro/lib.rs | 6 ++++++ src/librustc/Cargo.toml | 2 ++ src/librustc/lib.rs | 3 +++ src/librustc/util/common.rs | 21 +++++++++++++++++++ src/librustc_driver/driver.rs | 4 +++- src/test/ui-fulldeps/proc-macro/load-panic.rs | 1 + .../ui-fulldeps/proc-macro/load-panic.stderr | 4 ++-- 8 files changed, 40 insertions(+), 3 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index d8306c66daf84..5b56c6e12d624 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -1623,7 +1623,9 @@ dependencies = [ "fmt_macros 0.0.0", "graphviz 0.0.0", "jobserver 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)", + "lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", + "proc_macro 0.0.0", "rustc_apfloat 0.0.0", "rustc_back 0.0.0", "rustc_const_math 0.0.0", diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs index 6768e0ade4304..878a536836d23 100644 --- a/src/libproc_macro/lib.rs +++ b/src/libproc_macro/lib.rs @@ -844,6 +844,12 @@ pub mod __internal { }) } + pub fn in_sess() -> bool + { + let p = CURRENT_SESS.with(|p| p.get()); + !p.0.is_null() + } + pub fn with_sess<F, R>(f: F) -> R where F: FnOnce((&ParseSess, Mark)) -> R { diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 2c4898cb2c006..7e84a69dd7913 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -14,7 +14,9 @@ bitflags = "1.0" fmt_macros = { path = "../libfmt_macros" } graphviz = { path = "../libgraphviz" } jobserver = "0.1" +lazy_static = "1.0.0" log = { version = "0.4", features = ["release_max_level_info", "std"] } +proc_macro = { path = "../libproc_macro" } rustc_apfloat = { path = "../librustc_apfloat" } rustc_back = { path = "../librustc_back" } rustc_const_math = { path = "../librustc_const_math" } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index a7a2619505931..79333d1018ab1 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -60,6 +60,7 @@ #![feature(never_type)] #![feature(non_exhaustive)] #![feature(nonzero)] +#![feature(proc_macro_internals)] #![feature(quote)] #![feature(refcell_replace_swap)] #![feature(rustc_diagnostic_macros)] @@ -80,6 +81,7 @@ extern crate core; extern crate fmt_macros; extern crate getopts; extern crate graphviz; +#[macro_use] extern crate lazy_static; #[cfg(windows)] extern crate libc; extern crate rustc_back; @@ -91,6 +93,7 @@ extern crate rustc_errors as errors; #[macro_use] extern crate syntax; extern crate syntax_pos; extern crate jobserver; +extern crate proc_macro; extern crate serialize as rustc_serialize; // used by deriving diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 2971f3e853a99..55e9a98e7ef13 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -16,6 +16,7 @@ use std::ffi::CString; use std::fmt::Debug; use std::hash::{Hash, BuildHasher}; use std::iter::repeat; +use std::panic; use std::path::Path; use std::time::{Duration, Instant}; @@ -23,6 +24,8 @@ use std::sync::mpsc::{Sender}; use syntax_pos::{SpanData}; use ty::maps::{QueryMsg}; use dep_graph::{DepNode}; +use proc_macro; +use lazy_static; // The name of the associated type for `Fn` return types pub const FN_OUTPUT_NAME: &'static str = "Output"; @@ -34,6 +37,24 @@ pub struct ErrorReported; thread_local!(static TIME_DEPTH: Cell<usize> = Cell::new(0)); +lazy_static! { + static ref DEFAULT_HOOK: Box<Fn(&panic::PanicInfo) + Sync + Send + 'static> = { + let hook = panic::take_hook(); + panic::set_hook(Box::new(panic_hook)); + hook + }; +} + +fn panic_hook(info: &panic::PanicInfo) { + if !proc_macro::__internal::in_sess() { + (*DEFAULT_HOOK)(info) + } +} + +pub fn install_panic_hook() { + lazy_static::initialize(&DEFAULT_HOOK); +} + /// Initialized for -Z profile-queries thread_local!(static PROFQ_CHAN: RefCell<Option<Sender<ProfileQueriesMsg>>> = RefCell::new(None)); diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index b8a1fe9910540..eb67c9ce4b7d8 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -24,7 +24,7 @@ use rustc::middle::cstore::CrateStore; use rustc::middle::privacy::AccessLevels; use rustc::ty::{self, TyCtxt, Resolutions, AllArenas}; use rustc::traits; -use rustc::util::common::{ErrorReported, time}; +use rustc::util::common::{ErrorReported, time, install_panic_hook}; use rustc_allocator as allocator; use rustc_borrowck as borrowck; use rustc_incremental; @@ -123,6 +123,8 @@ pub fn compile_input(trans: Box<TransCrate>, let outputs = build_output_filenames(input, outdir, output, &krate.attrs, sess); let crate_name = ::rustc_trans_utils::link::find_crate_name(Some(sess), &krate.attrs, input); + install_panic_hook(); + let ExpansionResult { expanded_crate, defs, analysis, resolutions, mut hir_forest } = { phase_2_configure_and_expand( sess, diff --git a/src/test/ui-fulldeps/proc-macro/load-panic.rs b/src/test/ui-fulldeps/proc-macro/load-panic.rs index 328f398efd5c6..462eaf0341704 100644 --- a/src/test/ui-fulldeps/proc-macro/load-panic.rs +++ b/src/test/ui-fulldeps/proc-macro/load-panic.rs @@ -9,6 +9,7 @@ // except according to those terms. // aux-build:derive-panic.rs +// compile-flags:--error-format human #[macro_use] extern crate derive_panic; diff --git a/src/test/ui-fulldeps/proc-macro/load-panic.stderr b/src/test/ui-fulldeps/proc-macro/load-panic.stderr index 1be1609d45b2b..ab2ab84315a93 100644 --- a/src/test/ui-fulldeps/proc-macro/load-panic.stderr +++ b/src/test/ui-fulldeps/proc-macro/load-panic.stderr @@ -1,7 +1,7 @@ error: proc-macro derive panicked - --> $DIR/load-panic.rs:16:10 + --> $DIR/load-panic.rs:17:10 | -16 | #[derive(A)] +17 | #[derive(A)] | ^ | = help: message: nope!