Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Do not capture stderr in the compiler. Instead just panic silently for fatal errors #47634

Merged
merged 1 commit into from
Jan 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/librustc/hir/lowering.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2837,8 +2837,8 @@ impl<'a> LoweringContext<'a> {
(&None, &Some(..), Closed) => "RangeToInclusive",
(&Some(..), &Some(..), Closed) => "RangeInclusive",
(_, &None, Closed) =>
panic!(self.diagnostic().span_fatal(
e.span, "inclusive range with no end")),
self.diagnostic().span_fatal(
e.span, "inclusive range with no end").raise(),
};

let fields =
Expand Down
6 changes: 3 additions & 3 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1333,16 +1333,16 @@ pub fn build_target_config(opts: &Options, sp: &Handler) -> Config {
sp.struct_fatal(&format!("Error loading target specification: {}", e))
.help("Use `--print target-list` for a list of built-in targets")
.emit();
panic!(FatalError);
FatalError.raise();
}
};

let (isize_ty, usize_ty) = match &target.target_pointer_width[..] {
"16" => (ast::IntTy::I16, ast::UintTy::U16),
"32" => (ast::IntTy::I32, ast::UintTy::U32),
"64" => (ast::IntTy::I64, ast::UintTy::U64),
w => panic!(sp.fatal(&format!("target specification was invalid: \
unrecognized target-pointer-width {}", w))),
w => sp.fatal(&format!("target specification was invalid: \
unrecognized target-pointer-width {}", w)).raise(),
};

Config {
Expand Down
12 changes: 6 additions & 6 deletions src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,18 +250,18 @@ impl Session {
}

pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
panic!(self.diagnostic().span_fatal(sp, msg))
self.diagnostic().span_fatal(sp, msg).raise()
}
pub fn span_fatal_with_code<S: Into<MultiSpan>>(
&self,
sp: S,
msg: &str,
code: DiagnosticId,
) -> ! {
panic!(self.diagnostic().span_fatal_with_code(sp, msg, code))
self.diagnostic().span_fatal_with_code(sp, msg, code).raise()
}
pub fn fatal(&self, msg: &str) -> ! {
panic!(self.diagnostic().fatal(msg))
self.diagnostic().fatal(msg).raise()
}
pub fn span_err_or_warn<S: Into<MultiSpan>>(&self, is_warning: bool, sp: S, msg: &str) {
if is_warning {
Expand Down Expand Up @@ -919,7 +919,7 @@ pub fn build_session_(sopts: config::Options,
let host = match Target::search(config::host_triple()) {
Ok(t) => t,
Err(e) => {
panic!(span_diagnostic.fatal(&format!("Error loading host specification: {}", e)));
span_diagnostic.fatal(&format!("Error loading host specification: {}", e)).raise();
}
};
let target_cfg = config::build_target_config(&sopts, &span_diagnostic);
Expand All @@ -945,7 +945,7 @@ pub fn build_session_(sopts: config::Options,
let working_dir = match env::current_dir() {
Ok(dir) => dir,
Err(e) => {
panic!(p_s.span_diagnostic.fatal(&format!("Current directory is invalid: {}", e)))
p_s.span_diagnostic.fatal(&format!("Current directory is invalid: {}", e)).raise()
}
};
let working_dir = file_path_mapping.map_prefix(working_dir);
Expand Down Expand Up @@ -1076,7 +1076,7 @@ pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
};
let handler = errors::Handler::with_emitter(true, false, emitter);
handler.emit(&MultiSpan::new(), msg, errors::Level::Fatal);
panic!(errors::FatalError);
errors::FatalError.raise();
}

pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
Expand Down
35 changes: 7 additions & 28 deletions src/librustc_driver/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,11 @@ use std::env;
use std::ffi::OsString;
use std::io::{self, Read, Write};
use std::iter::repeat;
use std::panic;
use std::path::PathBuf;
use std::process::{self, Command, Stdio};
use std::rc::Rc;
use std::str;
use std::sync::{Arc, Mutex};
use std::thread;

use syntax::ast;
Expand Down Expand Up @@ -168,7 +168,7 @@ pub fn run<F>(run_compiler: F) -> isize
handler.emit(&MultiSpan::new(),
"aborting due to previous error(s)",
errors::Level::Fatal);
exit_on_err();
panic::resume_unwind(Box::new(errors::FatalErrorMarker));
}
}
}
Expand Down Expand Up @@ -1228,27 +1228,16 @@ pub fn in_rustc_thread<F, R>(f: F) -> Result<R, Box<Any + Send>>
/// The diagnostic emitter yielded to the procedure should be used for reporting
/// errors of the compiler.
pub fn monitor<F: FnOnce() + Send + 'static>(f: F) {
struct Sink(Arc<Mutex<Vec<u8>>>);
impl Write for Sink {
fn write(&mut self, data: &[u8]) -> io::Result<usize> {
Write::write(&mut *self.0.lock().unwrap(), data)
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}

let data = Arc::new(Mutex::new(Vec::new()));
let err = Sink(data.clone());

let result = in_rustc_thread(move || {
io::set_panic(Some(box err));
f()
});

if let Err(value) = result {
// Thread panicked without emitting a fatal diagnostic
if !value.is::<errors::FatalError>() {
if !value.is::<errors::FatalErrorMarker>() {
// Emit a newline
eprintln!("");

let emitter =
Box::new(errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto,
None,
Expand All @@ -1273,22 +1262,12 @@ pub fn monitor<F: FnOnce() + Send + 'static>(f: F) {
&note,
errors::Level::Note);
}

eprintln!("{}", str::from_utf8(&data.lock().unwrap()).unwrap());
}

exit_on_err();
panic::resume_unwind(Box::new(errors::FatalErrorMarker));
}
}

fn exit_on_err() -> ! {
// Panic so the process returns a failure code, but don't pollute the
// output with some unnecessary panic messages, we've already
// printed everything that we needed to.
io::set_panic(Some(box io::sink()));
panic!();
}

#[cfg(stage0)]
pub fn diagnostics_registry() -> errors::registry::Registry {
use errors::registry::Registry;
Expand Down
16 changes: 15 additions & 1 deletion src/librustc_errors/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#![cfg_attr(unix, feature(libc))]
#![feature(conservative_impl_trait)]
#![feature(i128_type)]
#![feature(optin_builtin_traits)]

extern crate term;
#[cfg(unix)]
Expand All @@ -44,6 +45,7 @@ use std::rc::Rc;
use std::{error, fmt};
use std::sync::atomic::AtomicUsize;
use std::sync::atomic::Ordering::SeqCst;
use std::panic;

mod diagnostic;
mod diagnostic_builder;
Expand Down Expand Up @@ -201,6 +203,18 @@ impl CodeSuggestion {
#[must_use]
pub struct FatalError;

pub struct FatalErrorMarker;

// Don't implement Send on FatalError. This makes it impossible to panic!(FatalError).
// We don't want to invoke the panic handler and print a backtrace for fatal errors.
impl !Send for FatalError {}

impl FatalError {
pub fn raise(self) -> ! {
panic::resume_unwind(Box::new(FatalErrorMarker))
}
}

impl fmt::Display for FatalError {
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
write!(f, "parser fatal error")
Expand Down Expand Up @@ -539,7 +553,7 @@ impl Handler {
}
}

panic!(self.fatal(&s));
self.fatal(&s).raise();
}
pub fn emit(&self, msp: &MultiSpan, msg: &str, lvl: Level) {
if lvl == Warning && !self.flags.can_emit_warnings {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_trans/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ fn get_llvm_opt_size(optimize: config::OptLevel) -> llvm::CodeGenOptSize {

pub fn create_target_machine(sess: &Session) -> TargetMachineRef {
target_machine_factory(sess)().unwrap_or_else(|err| {
panic!(llvm_err(sess.diagnostic(), err))
llvm_err(sess.diagnostic(), err).raise()
})
}

Expand Down Expand Up @@ -582,7 +582,7 @@ fn generate_lto_work(cgcx: &CodegenContext,
lto::LTOMode::JustThisCrate
};
let lto_modules = lto::run(cgcx, modules, mode, &mut timeline)
.unwrap_or_else(|e| panic!(e));
.unwrap_or_else(|e| e.raise());

lto_modules.into_iter().map(|module| {
let cost = module.cost();
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ext/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,7 @@ impl<'a> ExtCtxt<'a> {
/// substitute; we never hit resolve/type-checking so the dummy
/// value doesn't have to match anything)
pub fn span_fatal<S: Into<MultiSpan>>(&self, sp: S, msg: &str) -> ! {
panic!(self.parse_sess.span_diagnostic.span_fatal(sp, msg));
self.parse_sess.span_diagnostic.span_fatal(sp, msg).raise();
}

/// Emit `msg` attached to `sp`, without immediately stopping
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/ext/expand.rs
Original file line number Diff line number Diff line change
Expand Up @@ -455,7 +455,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
suggested_limit));
err.emit();
self.cx.trace_macros_diag();
panic!(FatalError);
FatalError.raise();
}

Some(result)
Expand Down
5 changes: 3 additions & 2 deletions src/libsyntax/ext/source_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,9 +116,10 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::T
while self.p.token != token::Eof {
match panictry!(self.p.parse_item()) {
Some(item) => ret.push(item),
None => panic!(self.p.diagnostic().span_fatal(self.p.span,
None => self.p.diagnostic().span_fatal(self.p.span,
&format!("expected item, found `{}`",
self.p.this_token_to_string())))
self.p.this_token_to_string()))
.raise()
}
}
Some(ret)
Expand Down
6 changes: 3 additions & 3 deletions src/libsyntax/ext/tt/macro_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -573,15 +573,15 @@ fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal {
Some(i) => token::NtItem(i),
None => {
p.fatal("expected an item keyword").emit();
panic!(FatalError);
FatalError.raise();
}
},
"block" => token::NtBlock(panictry!(p.parse_block())),
"stmt" => match panictry!(p.parse_stmt()) {
Some(s) => token::NtStmt(s),
None => {
p.fatal("expected a statement").emit();
panic!(FatalError);
FatalError.raise();
}
},
"pat" => token::NtPat(panictry!(p.parse_pat())),
Expand All @@ -597,7 +597,7 @@ fn parse_nt<'a>(p: &mut Parser<'a>, sp: Span, name: &str) -> Nonterminal {
let token_str = pprust::token_to_string(&p.token);
p.fatal(&format!("expected ident, found {}",
&token_str[..])).emit();
panic!(FatalError)
FatalError.raise()
}
},
"path" => token::NtPath(panictry!(p.parse_path_common(PathStyle::Type, false))),
Expand Down
4 changes: 2 additions & 2 deletions src/libsyntax/ext/tt/macro_rules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,10 @@ pub fn compile(sess: &ParseSess, features: &RefCell<Features>, def: &ast::Item)
Success(m) => m,
Failure(sp, tok) => {
let s = parse_failure_msg(tok);
panic!(sess.span_diagnostic.span_fatal(sp.substitute_dummy(def.span), &s));
sess.span_diagnostic.span_fatal(sp.substitute_dummy(def.span), &s).raise();
}
Error(sp, s) => {
panic!(sess.span_diagnostic.span_fatal(sp.substitute_dummy(def.span), &s));
sess.span_diagnostic.span_fatal(sp.substitute_dummy(def.span), &s).raise();
}
};

Expand Down
4 changes: 2 additions & 2 deletions src/libsyntax/feature_gate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1954,7 +1954,7 @@ impl FeatureChecker {
.span_note(ca_span, "`#![feature(custom_attribute)]` declared here")
.emit();

panic!(FatalError);
FatalError.raise();
}

if let (Some(span), None) = (self.copy_closures, self.clone_closures) {
Expand All @@ -1963,7 +1963,7 @@ impl FeatureChecker {
.span_note(span, "`#![feature(copy_closures)]` declared here")
.emit();

panic!(FatalError);
FatalError.raise();
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ macro_rules! panictry {
Ok(e) => e,
Err(mut e) => {
e.emit();
panic!(FatalError);
FatalError.raise()
}
}
})
Expand Down
2 changes: 1 addition & 1 deletion src/libsyntax/parse/lexer/comments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ fn read_block_comment(rdr: &mut StringReader,
while level > 0 {
debug!("=== block comment level {}", level);
if rdr.is_eof() {
panic!(rdr.fatal("unterminated block comment"));
rdr.fatal("unterminated block comment").raise();
}
if rdr.ch_is('\n') {
trim_whitespace_prefix_and_push_line(&mut lines, curr_line, col);
Expand Down
Loading