Skip to content

Commit 6f8a6b6

Browse files
committed
implement error handling for codegen()
it no longer returns Result, so instead of unwrapping, I implemented errors
1 parent 027bbf8 commit 6f8a6b6

File tree

4 files changed

+70
-24
lines changed

4 files changed

+70
-24
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
codegen_c_cc_spawn_err = Failed to spawn C compiler : {$err}
2+
3+
codegen_c_cc_err = C compiler returned an error. stderr : `{$cc_stderr}`; stdout : `{$cc_stdout}`
4+
5+
codegen_c_c_file_write_err = Failed to write C source file : {$err}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
use rustc_macros::Diagnostic;
2+
3+
#[derive(Diagnostic)]
4+
#[diag(codegen_c_c_file_write_err)]
5+
pub(crate) struct CFileWriteError {
6+
pub err: std::io::Error,
7+
}
8+
9+
#[derive(Diagnostic)]
10+
#[diag(codegen_c_cc_spawn_err)]
11+
pub(crate) struct CCompilerSpawnError {
12+
pub err: std::io::Error,
13+
}
14+
15+
#[derive(Diagnostic)]
16+
#[diag(codegen_c_cc_err)]
17+
pub(crate) struct CCompilerError {
18+
pub cc_stderr: String,
19+
pub cc_stdout: String,
20+
}

crates/rustc_codegen_c/src/lib.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ extern crate rustc_errors;
1010
extern crate rustc_fluent_macro;
1111
extern crate rustc_hash;
1212
extern crate rustc_hir;
13+
extern crate rustc_macros;
1314
extern crate rustc_metadata;
1415
extern crate rustc_middle;
1516
extern crate rustc_session;
@@ -44,6 +45,7 @@ mod archive;
4445
mod base;
4546
mod builder;
4647
mod context;
48+
mod errors;
4749
mod write;
4850

4951
rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
@@ -149,7 +151,6 @@ impl WriteBackendMethods for CCodegen {
149151

150152
fn run_thin_lto(
151153
_cgcx: &CodegenContext<Self>,
152-
// FIXME(bjorn3): Limit LTO exports to these symbols
153154
_exported_symbols_for_lto: &[String],
154155
_each_linked_rlib_for_lto: &[PathBuf],
155156
_modules: Vec<(String, Self::ThinBuffer)>,

crates/rustc_codegen_c/src/write.rs

Lines changed: 43 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use std::fs;
2-
use std::io::Write;
2+
use std::io::{self, Write};
3+
use std::path::PathBuf;
34
use std::process::{Command, Stdio};
45

56
use rustc_codegen_ssa::back::write::{CodegenContext, ModuleConfig};
@@ -8,11 +9,33 @@ use rustc_errors::{DiagCtxtHandle, FatalError};
89
use rustc_session::config::OutputType;
910
use tracing::error;
1011

12+
fn write_module(c_out: &PathBuf, module: &ModuleCodegen<String>) -> io::Result<()> {
13+
let mut c_out_file = fs::File::create(c_out)?;
14+
writeln!(c_out_file, "// file: {}.c", module.name)?;
15+
write!(c_out_file, "{}", module.module_llvm)?;
16+
Ok(())
17+
}
18+
fn compiled_module(
19+
success: bool,
20+
module: ModuleCodegen<String>,
21+
cgcx: &CodegenContext<crate::CCodegen>,
22+
) -> CompiledModule {
23+
module.into_compiled_module(
24+
success,
25+
false,
26+
false,
27+
false,
28+
false,
29+
&cgcx.output_filenames,
30+
cgcx.invocation_temp.as_deref(),
31+
)
32+
}
33+
1134
pub(crate) fn codegen(
1235
cgcx: &CodegenContext<crate::CCodegen>,
1336
module: ModuleCodegen<String>,
1437
_config: &ModuleConfig,
15-
) -> Result<CompiledModule, FatalError> {
38+
) -> CompiledModule {
1639
let dcx = cgcx.create_dcx();
1740
let dcx = dcx.handle();
1841
let obj_out = cgcx.output_filenames.temp_path_for_cgu(
@@ -23,44 +46,41 @@ pub(crate) fn codegen(
2346
let c_out = obj_out.with_extension("c");
2447

2548
// output c source code
26-
let c_out_file = fs::File::create(&c_out).map_err(|_| FatalError)?;
27-
writeln!(&c_out_file, "// file: {}.c", module.name).map_err(|_| FatalError)?;
28-
write!(&c_out_file, "{}", module.module_llvm).map_err(|_| FatalError)?;
49+
if let Err(c_out_err) = write_module(&c_out, &module) {
50+
dcx.emit_err(crate::errors::CFileWriteError { err: c_out_err });
51+
return compiled_module(false, module, cgcx);
52+
}
2953

3054
// invoke cc to compile
3155
// FIXME: configure cc
3256
// FIXME: handle long command line (windows)
3357
// FIXME: flush_linked_file (windows)
3458
let mut cmd = Command::new("clang");
3559
cmd.arg(&c_out).arg("-o").arg(&obj_out).arg("-c");
36-
let output = match cmd
60+
let success = match cmd
3761
.stdout(Stdio::piped())
3862
.stderr(Stdio::piped())
3963
.spawn()
4064
.and_then(|child| child.wait_with_output())
4165
{
42-
Ok(output) => output,
66+
Ok(output) if !output.status.success() => {
67+
error!("compiler stderr:\n{}", String::from_utf8_lossy(&output.stderr));
68+
error!("compiler stdout:\n{}", String::from_utf8_lossy(&output.stdout));
69+
dcx.emit_err(crate::errors::CCompilerError {
70+
cc_stderr: String::from_utf8_lossy(&output.stderr).to_string(),
71+
cc_stdout: String::from_utf8_lossy(&output.stdout).to_string(),
72+
});
73+
false
74+
}
75+
Ok(_) => true,
4376
Err(e) => {
4477
error!("failed to spawn C compiler: {}", e);
45-
return Err(FatalError);
78+
dcx.emit_err(crate::errors::CCompilerSpawnError { err: e });
79+
false
4680
}
4781
};
4882

49-
if !output.status.success() {
50-
error!("compiler stderr:\n{}", String::from_utf8_lossy(&output.stderr));
51-
error!("compiler stdout:\n{}", String::from_utf8_lossy(&output.stdout));
52-
return Err(FatalError);
53-
}
54-
55-
Ok(module.into_compiled_module(
56-
true,
57-
false,
58-
false,
59-
false,
60-
false,
61-
&cgcx.output_filenames,
62-
cgcx.invocation_temp.as_deref(),
63-
))
83+
compiled_module(success, module, cgcx)
6484
}
6585

6686
pub(crate) fn link(

0 commit comments

Comments
 (0)