Skip to content

Commit a8247dd

Browse files
committed
Auto merge of #52197 - euclio:exit-code, r=oli-obk
overhaul exit codes for rustc and rustdoc This commit changes the exit status of rustc to 1 in the presence of compilation errors. In the event of an unexpected panic (ICE) the standard panic error exit status of 101 remains. A run-make test is added to ensure that the exit code does not regress, and compiletest is updated to check for an exit status of 1 or 101, depending on the mode and suite. This is a breaking change for custom drivers. Note that while changes were made to the rustdoc binary, there is no intended behavior change. rustdoc errors (i.e., failed lints) will still report 101. While this could *also* hide potential ICEs, I will leave that work to a future PR. Fixes #51971.
2 parents 5ba2184 + 8f4ccac commit a8247dd

File tree

9 files changed

+110
-25
lines changed

9 files changed

+110
-25
lines changed

src/librustc_driver/lib.rs

+35-13
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,9 @@ use std::cmp::max;
9494
use std::default::Default;
9595
use std::env::consts::{DLL_PREFIX, DLL_SUFFIX};
9696
use std::env;
97+
use std::error::Error;
9798
use std::ffi::OsString;
99+
use std::fmt::{self, Display};
98100
use std::io::{self, Read, Write};
99101
use std::iter::repeat;
100102
use std::mem;
@@ -146,6 +148,12 @@ pub mod target_features {
146148
}
147149
}
148150

151+
/// Exit status code used for successful compilation and help output.
152+
pub const EXIT_SUCCESS: isize = 0;
153+
154+
/// Exit status code used for compilation failures and invalid flags.
155+
pub const EXIT_FAILURE: isize = 1;
156+
149157
const BUG_REPORT_URL: &'static str = "https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.\
150158
md#bug-reports";
151159

@@ -178,7 +186,7 @@ pub fn abort_on_err<T>(result: Result<T, CompileIncomplete>, sess: &Session) ->
178186
pub fn run<F>(run_compiler: F) -> isize
179187
where F: FnOnce() -> (CompileResult, Option<Session>) + Send + 'static
180188
{
181-
monitor(move || {
189+
let result = monitor(move || {
182190
let (result, session) = run_compiler();
183191
if let Err(CompileIncomplete::Errored(_)) = result {
184192
match session {
@@ -201,7 +209,11 @@ pub fn run<F>(run_compiler: F) -> isize
201209
}
202210
}
203211
});
204-
0
212+
213+
match result {
214+
Ok(()) => EXIT_SUCCESS,
215+
Err(_) => EXIT_FAILURE,
216+
}
205217
}
206218

207219
fn load_backend_from_dylib(path: &Path) -> fn() -> Box<dyn CodegenBackend> {
@@ -1625,20 +1637,30 @@ fn extra_compiler_flags() -> Option<(Vec<String>, bool)> {
16251637
}
16261638
}
16271639

1640+
#[derive(Debug)]
1641+
pub struct CompilationFailure;
1642+
1643+
impl Error for CompilationFailure {}
1644+
1645+
impl Display for CompilationFailure {
1646+
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
1647+
write!(f, "compilation had errors")
1648+
}
1649+
}
1650+
16281651
/// Run a procedure which will detect panics in the compiler and print nicer
16291652
/// error messages rather than just failing the test.
16301653
///
16311654
/// The diagnostic emitter yielded to the procedure should be used for reporting
16321655
/// errors of the compiler.
1633-
pub fn monitor<F: FnOnce() + Send + 'static>(f: F) {
1634-
let result = in_rustc_thread(move || {
1656+
pub fn monitor<F: FnOnce() + Send + 'static>(f: F) -> Result<(), CompilationFailure> {
1657+
in_rustc_thread(move || {
16351658
f()
1636-
});
1637-
1638-
if let Err(value) = result {
1639-
// Thread panicked without emitting a fatal diagnostic
1640-
if !value.is::<errors::FatalErrorMarker>() {
1641-
// Emit a newline
1659+
}).map_err(|value| {
1660+
if value.is::<errors::FatalErrorMarker>() {
1661+
CompilationFailure
1662+
} else {
1663+
// Thread panicked without emitting a fatal diagnostic
16421664
eprintln!("");
16431665

16441666
let emitter =
@@ -1677,10 +1699,10 @@ pub fn monitor<F: FnOnce() + Send + 'static>(f: F) {
16771699
&note,
16781700
errors::Level::Note);
16791701
}
1680-
}
16811702

1682-
panic::resume_unwind(Box::new(errors::FatalErrorMarker));
1683-
}
1703+
panic::resume_unwind(Box::new(errors::FatalErrorMarker));
1704+
}
1705+
})
16841706
}
16851707

16861708
pub fn diagnostics_registry() -> errors::registry::Registry {

src/librustdoc/lib.rs

+8-3
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ use errors::ColorConfig;
5757
use std::collections::{BTreeMap, BTreeSet};
5858
use std::default::Default;
5959
use std::env;
60+
use std::panic;
6061
use std::path::{Path, PathBuf};
6162
use std::process;
6263
use std::sync::mpsc::channel;
@@ -115,7 +116,7 @@ pub fn main() {
115116
syntax::with_globals(move || {
116117
get_args().map(|args| main_args(&args)).unwrap_or(1)
117118
})
118-
}).unwrap().join().unwrap_or(101);
119+
}).unwrap().join().unwrap_or(rustc_driver::EXIT_FAILURE);
119120
process::exit(res as i32);
120121
}
121122

@@ -667,7 +668,7 @@ where R: 'static + Send,
667668

668669
let (tx, rx) = channel();
669670

670-
rustc_driver::monitor(move || syntax::with_globals(move || {
671+
let result = rustc_driver::monitor(move || syntax::with_globals(move || {
671672
use rustc::session::config::Input;
672673

673674
let (mut krate, renderinfo) =
@@ -771,7 +772,11 @@ where R: 'static + Send,
771772

772773
tx.send(f(Output { krate: krate, renderinfo: renderinfo, passes: passes })).unwrap();
773774
}));
774-
rx.recv().unwrap()
775+
776+
match result {
777+
Ok(()) => rx.recv().unwrap(),
778+
Err(_) => panic::resume_unwind(Box::new(errors::FatalErrorMarker)),
779+
}
775780
}
776781

777782
/// Prints deprecation warnings for deprecated options
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
-include ../tools.mk
2+
3+
all:
4+
$(RUSTC) success.rs; [ $$? -eq 0 ]
5+
$(RUSTC) --invalid-arg-foo; [ $$? -eq 1 ]
6+
$(RUSTC) compile-error.rs; [ $$? -eq 1 ]
7+
$(RUSTC) -Ztreat-err-as-bug compile-error.rs; [ $$? -eq 101 ]
8+
$(RUSTDOC) -o $(TMPDIR)/exit-code success.rs; [ $$? -eq 0 ]
9+
$(RUSTDOC) --invalid-arg-foo; [ $$? -eq 1 ]
10+
$(RUSTDOC) compile-error.rs; [ $$? -eq 1 ]
11+
$(RUSTDOC) lint-failure.rs; [ $$? -eq 1 ]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn main() {
12+
compile_error!("kaboom");
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![deny(intra_doc_link_resolution_failure)]
12+
13+
/// [intradoc::failure]
14+
fn main() {
15+
println!("Hello, world!");
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
/// Main function
12+
fn main() {
13+
println!("Hello, world!");
14+
}

src/test/ui/issue-20801.rs

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
// ignore-test currently ICEs when using NLL (#52416)
12+
1113
// We used to ICE when moving out of a `*mut T` or `*const T`.
1214

1315
struct T(u8);

src/tools/compiletest/src/header.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ use std::io::prelude::*;
1414
use std::io::BufReader;
1515
use std::path::{Path, PathBuf};
1616

17-
use common;
18-
use common::Config;
17+
use common::{self, Config, Mode};
1918
use util;
2019

2120
use extract_gdb_version;
@@ -262,7 +261,7 @@ impl TestProps {
262261
disable_ui_testing_normalization: false,
263262
normalize_stdout: vec![],
264263
normalize_stderr: vec![],
265-
failure_status: 101,
264+
failure_status: -1,
266265
run_rustfix: false,
267266
}
268267
}
@@ -393,6 +392,11 @@ impl TestProps {
393392

394393
if let Some(code) = config.parse_failure_status(ln) {
395394
self.failure_status = code;
395+
} else {
396+
self.failure_status = match config.mode {
397+
Mode::RunFail => 101,
398+
_ => 1,
399+
};
396400
}
397401

398402
if !self.run_rustfix {

src/tools/compiletest/src/runtest.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -1170,12 +1170,10 @@ impl<'test> TestCx<'test> {
11701170
}
11711171

11721172
fn check_no_compiler_crash(&self, proc_res: &ProcRes) {
1173-
for line in proc_res.stderr.lines() {
1174-
if line.contains("error: internal compiler error") {
1175-
self.fatal_proc_rec("compiler encountered internal error", proc_res);
1176-
} else if line.contains(" panicked at ") {
1177-
self.fatal_proc_rec("compiler panicked", proc_res);
1178-
}
1173+
match proc_res.status.code() {
1174+
Some(101) => self.fatal_proc_rec("compiler encountered internal error", proc_res),
1175+
None => self.fatal_proc_rec("compiler terminated by signal", proc_res),
1176+
_ => (),
11791177
}
11801178
}
11811179

0 commit comments

Comments
 (0)