diff --git a/crates/nargo/src/cli/check_cmd.rs b/crates/nargo/src/cli/check_cmd.rs index 2dc1fc7ff21..a90595f1592 100644 --- a/crates/nargo/src/cli/check_cmd.rs +++ b/crates/nargo/src/cli/check_cmd.rs @@ -32,9 +32,7 @@ fn check_from_path>(p: P, compile_options: &CompileOptions) -> Re let mut driver = Resolver::resolve_root_config(p.as_ref(), backend.np_language())?; add_std_lib(&mut driver); - if driver.check_crate(compile_options).is_err() { - std::process::exit(1); - } + driver.check_crate(compile_options).map_err(|_| CliError::CompilationError)?; // XXX: We can have a --overwrite flag to determine if you want to overwrite the Prover/Verifier.toml files if let Some((parameters, return_type)) = driver.compute_function_signature() { diff --git a/crates/nargo/src/cli/compile_cmd.rs b/crates/nargo/src/cli/compile_cmd.rs index 71d6ceef6f6..c3022a75604 100644 --- a/crates/nargo/src/cli/compile_cmd.rs +++ b/crates/nargo/src/cli/compile_cmd.rs @@ -45,7 +45,7 @@ pub(crate) fn run(mut args: CompileCommand, config: NargoConfig) -> Result<(), C } Ok(()) } else { - let main = driver.main_function(); + let main = driver.main_function().map_err(|_| CliError::CompilationError)?; compile_and_save_program(&driver, main, &args, &circuit_dir) } } diff --git a/crates/nargo/src/cli/test_cmd.rs b/crates/nargo/src/cli/test_cmd.rs index 01c21e1ac57..abc8cde9dc2 100644 --- a/crates/nargo/src/cli/test_cmd.rs +++ b/crates/nargo/src/cli/test_cmd.rs @@ -36,9 +36,7 @@ fn run_tests( let mut driver = Resolver::resolve_root_config(program_dir, backend.np_language())?; add_std_lib(&mut driver); - if driver.check_crate(compile_options).is_err() { - std::process::exit(1); - } + driver.check_crate(compile_options).map_err(|_| CliError::CompilationError)?; let test_functions = driver.get_all_test_functions_in_crate_matching(test_name); println!("Running {} test functions...", test_functions.len()); @@ -68,9 +66,7 @@ fn run_tests( writeln!(writer, "All tests passed").ok(); } else { let plural = if failing == 1 { "" } else { "s" }; - writer.set_color(ColorSpec::new().set_fg(Some(Color::Red))).unwrap(); - writeln!(writer, "{failing} test{plural} failed").ok(); - std::process::exit(1); + return Err(CliError::Generic(format!("{failing} test{plural} failed"))); } writer.reset().ok(); diff --git a/crates/noirc_driver/src/lib.rs b/crates/noirc_driver/src/lib.rs index 246cb2c71b8..990da29b1a0 100644 --- a/crates/noirc_driver/src/lib.rs +++ b/crates/noirc_driver/src/lib.rs @@ -53,10 +53,13 @@ impl Driver { // This is here for backwards compatibility // with the restricted version which only uses one file - pub fn compile_file(root_file: PathBuf, np_language: acvm::Language) -> CompiledProgram { + pub fn compile_file( + root_file: PathBuf, + np_language: acvm::Language, + ) -> Result { let mut driver = Driver::new(&np_language); driver.create_local_crate(root_file, CrateType::Binary); - driver.compile_main(&CompileOptions::default()).unwrap_or_else(|_| std::process::exit(1)) + driver.compile_main(&CompileOptions::default()) } /// Compiles a file and returns true if compilation was successful @@ -167,14 +170,20 @@ impl Driver { options: &CompileOptions, ) -> Result { self.check_crate(options)?; - let main = self.main_function(); + let main = match self.main_function() { + Ok(m) => m, + Err(e) => { + println!("cannot compile a program with no main function"); + return Err(e); + } + }; self.compile_no_check(options, main) } /// Returns the FuncId of the 'main' funciton. /// - Expects check_crate to be called beforehand /// - Panics if no main function is found - pub fn main_function(&self) -> FuncId { + pub fn main_function(&self) -> Result { // Find the local crate, one should always be present let local_crate = self.context.def_map(LOCAL_CRATE).unwrap(); @@ -182,11 +191,14 @@ impl Driver { // We don't panic here to allow users to `evaluate` libraries which will do nothing if self.context.crate_graph[LOCAL_CRATE].crate_type != CrateType::Binary { println!("cannot compile crate into a program as the local crate is not a binary. For libraries, please use the check command"); - std::process::exit(1); + return Err(ReportedError); }; // All Binaries should have a main function - local_crate.main_function().expect("cannot compile a program with no main function") + match local_crate.main_function() { + Some(func_id) => Ok(func_id), + None => Err(ReportedError), + } } /// Compile the current crate. Assumes self.check_crate is called beforehand! diff --git a/crates/wasm/src/lib.rs b/crates/wasm/src/lib.rs index 67325923953..b4c8e9b388f 100644 --- a/crates/wasm/src/lib.rs +++ b/crates/wasm/src/lib.rs @@ -28,7 +28,10 @@ pub fn compile(src: String) -> JsValue { // For now we default to plonk width = 3, though we can add it as a parameter let language = acvm::Language::PLONKCSat { width: 3 }; let path = PathBuf::from(src); - let compiled_program = noirc_driver::Driver::compile_file(path, language); + let compiled_program = match noirc_driver::Driver::compile_file(path, language) { + Ok(compiled_program) => compiled_program, + Err(_) => panic!("Compilation Error: Failed to compile circuit"), + }; ::from_serde(&compiled_program).unwrap() }