diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 0e1ba6e444d..f60954ea021 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -94,7 +94,9 @@ use std::cmp::max; use std::default::Default; use std::env::consts::{DLL_PREFIX, DLL_SUFFIX}; use std::env; +use std::error::Error; use std::ffi::OsString; +use std::fmt::{self, Display}; use std::io::{self, Read, Write}; use std::iter::repeat; use std::mem; @@ -146,6 +148,12 @@ pub mod target_features { } } +/// Exit status code used for successful compilation and help output. +pub const EXIT_SUCCESS: isize = 0; + +/// Exit status code used for compilation failures and invalid flags. +pub const EXIT_FAILURE: isize = 1; + const BUG_REPORT_URL: &'static str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\ md#bug-reports"; @@ -178,7 +186,7 @@ pub fn abort_on_err(result: Result, sess: &Session) -> pub fn run(run_compiler: F) -> isize where F: FnOnce() -> (CompileResult, Option) + Send + 'static { - monitor(move || { + let result = monitor(move || { let (result, session) = run_compiler(); if let Err(CompileIncomplete::Errored(_)) = result { match session { @@ -201,7 +209,11 @@ pub fn run(run_compiler: F) -> isize } } }); - 0 + + match result { + Ok(()) => EXIT_SUCCESS, + Err(_) => EXIT_FAILURE, + } } fn load_backend_from_dylib(path: &Path) -> fn() -> Box { @@ -1625,20 +1637,30 @@ fn extra_compiler_flags() -> Option<(Vec, bool)> { } } +#[derive(Debug)] +pub struct CompilationFailure; + +impl Error for CompilationFailure {} + +impl Display for CompilationFailure { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "compilation had errors") + } +} + /// Run a procedure which will detect panics in the compiler and print nicer /// error messages rather than just failing the test. /// /// The diagnostic emitter yielded to the procedure should be used for reporting /// errors of the compiler. -pub fn monitor(f: F) { - let result = in_rustc_thread(move || { +pub fn monitor(f: F) -> Result<(), CompilationFailure> { + in_rustc_thread(move || { f() - }); - - if let Err(value) = result { - // Thread panicked without emitting a fatal diagnostic - if !value.is::() { - // Emit a newline + }).map_err(|value| { + if value.is::() { + CompilationFailure + } else { + // Thread panicked without emitting a fatal diagnostic eprintln!(""); let emitter = @@ -1677,10 +1699,10 @@ pub fn monitor(f: F) { ¬e, errors::Level::Note); } - } - panic::resume_unwind(Box::new(errors::FatalErrorMarker)); - } + panic::resume_unwind(Box::new(errors::FatalErrorMarker)); + } + }) } pub fn diagnostics_registry() -> errors::registry::Registry { diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 3e26ed2b97c..089ecebbc9c 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -57,6 +57,7 @@ use errors::ColorConfig; use std::collections::{BTreeMap, BTreeSet}; use std::default::Default; use std::env; +use std::panic; use std::path::{Path, PathBuf}; use std::process; use std::sync::mpsc::channel; @@ -115,7 +116,7 @@ pub fn main() { syntax::with_globals(move || { get_args().map(|args| main_args(&args)).unwrap_or(1) }) - }).unwrap().join().unwrap_or(101); + }).unwrap().join().unwrap_or(rustc_driver::EXIT_FAILURE); process::exit(res as i32); } @@ -667,7 +668,7 @@ where R: 'static + Send, let (tx, rx) = channel(); - rustc_driver::monitor(move || syntax::with_globals(move || { + let result = rustc_driver::monitor(move || syntax::with_globals(move || { use rustc::session::config::Input; let (mut krate, renderinfo) = @@ -771,7 +772,11 @@ where R: 'static + Send, tx.send(f(Output { krate: krate, renderinfo: renderinfo, passes: passes })).unwrap(); })); - rx.recv().unwrap() + + match result { + Ok(()) => rx.recv().unwrap(), + Err(_) => panic::resume_unwind(Box::new(errors::FatalErrorMarker)), + } } /// Prints deprecation warnings for deprecated options diff --git a/src/test/run-make-fulldeps/exit-code/Makefile b/src/test/run-make-fulldeps/exit-code/Makefile new file mode 100644 index 00000000000..007f19852a6 --- /dev/null +++ b/src/test/run-make-fulldeps/exit-code/Makefile @@ -0,0 +1,11 @@ +-include ../tools.mk + +all: + $(RUSTC) success.rs; [ $$? -eq 0 ] + $(RUSTC) --invalid-arg-foo; [ $$? -eq 1 ] + $(RUSTC) compile-error.rs; [ $$? -eq 1 ] + $(RUSTC) -Ztreat-err-as-bug compile-error.rs; [ $$? -eq 101 ] + $(RUSTDOC) -o $(TMPDIR)/exit-code success.rs; [ $$? -eq 0 ] + $(RUSTDOC) --invalid-arg-foo; [ $$? -eq 1 ] + $(RUSTDOC) compile-error.rs; [ $$? -eq 1 ] + $(RUSTDOC) lint-failure.rs; [ $$? -eq 1 ] diff --git a/src/test/run-make-fulldeps/exit-code/compile-error.rs b/src/test/run-make-fulldeps/exit-code/compile-error.rs new file mode 100644 index 00000000000..8c05318a508 --- /dev/null +++ b/src/test/run-make-fulldeps/exit-code/compile-error.rs @@ -0,0 +1,13 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn main() { + compile_error!("kaboom"); +} diff --git a/src/test/run-make-fulldeps/exit-code/lint-failure.rs b/src/test/run-make-fulldeps/exit-code/lint-failure.rs new file mode 100644 index 00000000000..3bf40b753c1 --- /dev/null +++ b/src/test/run-make-fulldeps/exit-code/lint-failure.rs @@ -0,0 +1,16 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#![deny(intra_doc_link_resolution_failure)] + +/// [intradoc::failure] +fn main() { + println!("Hello, world!"); +} diff --git a/src/test/run-make-fulldeps/exit-code/success.rs b/src/test/run-make-fulldeps/exit-code/success.rs new file mode 100644 index 00000000000..9f6c5734a30 --- /dev/null +++ b/src/test/run-make-fulldeps/exit-code/success.rs @@ -0,0 +1,14 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +/// Main function +fn main() { + println!("Hello, world!"); +} diff --git a/src/test/ui/issue-20801.rs b/src/test/ui/issue-20801.rs index d3b97a9c058..0e8b7fb9037 100644 --- a/src/test/ui/issue-20801.rs +++ b/src/test/ui/issue-20801.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +// ignore-test currently ICEs when using NLL (#52416) + // We used to ICE when moving out of a `*mut T` or `*const T`. struct T(u8); diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs index 1dd7fe7f0cb..edab2a5ec03 100644 --- a/src/tools/compiletest/src/header.rs +++ b/src/tools/compiletest/src/header.rs @@ -14,8 +14,7 @@ use std::io::prelude::*; use std::io::BufReader; use std::path::{Path, PathBuf}; -use common; -use common::Config; +use common::{self, Config, Mode}; use util; use extract_gdb_version; @@ -262,7 +261,7 @@ impl TestProps { disable_ui_testing_normalization: false, normalize_stdout: vec![], normalize_stderr: vec![], - failure_status: 101, + failure_status: -1, run_rustfix: false, } } @@ -393,6 +392,11 @@ impl TestProps { if let Some(code) = config.parse_failure_status(ln) { self.failure_status = code; + } else { + self.failure_status = match config.mode { + Mode::RunFail => 101, + _ => 1, + }; } if !self.run_rustfix { diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 59ddc16715d..fcc47436225 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -1170,12 +1170,10 @@ impl<'test> TestCx<'test> { } fn check_no_compiler_crash(&self, proc_res: &ProcRes) { - for line in proc_res.stderr.lines() { - if line.contains("error: internal compiler error") { - self.fatal_proc_rec("compiler encountered internal error", proc_res); - } else if line.contains(" panicked at ") { - self.fatal_proc_rec("compiler panicked", proc_res); - } + match proc_res.status.code() { + Some(101) => self.fatal_proc_rec("compiler encountered internal error", proc_res), + None => self.fatal_proc_rec("compiler terminated by signal", proc_res), + _ => (), } }