From ef5cacef65bed736ee0bdff7426684b3c1b5e35f Mon Sep 17 00:00:00 2001 From: Miquel Sabaté Solà Date: Mon, 24 Aug 2026 14:16:42 +0200 Subject: Annotate the no-return from die() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In all crates we are using a die() function to print to stderr and quit with a exit status > 0. Apparently in Rust you can annotate the return type with a bang just like the noreturn from the C family. The added bonus is that some useless statements to make the compiler happy without it can be removed altogether as now the compiler is able to understand that it won't return so the returned type is not needed. Signed-off-by: Miquel Sabaté Solà --- crates/nasm/src/main.rs | 35 +++++++++++++---------------------- crates/readrom/src/main.rs | 8 ++------ crates/runrom/src/main.rs | 9 ++------- crates/xa65/src/main.rs | 31 +++++++++++-------------------- 4 files changed, 28 insertions(+), 55 deletions(-) (limited to 'crates') diff --git a/crates/nasm/src/main.rs b/crates/nasm/src/main.rs index 010e7d5..a5c446f 100644 --- a/crates/nasm/src/main.rs +++ b/crates/nasm/src/main.rs @@ -77,7 +77,6 @@ fn parse_define(arg: &str) -> (String, u8) { let Some(name) = key_value.next() else { die(format!("bad format for define '{arg}'")); - return (String::default(), 0); }; if name @@ -95,7 +94,6 @@ fn parse_define(arg: &str) -> (String, u8) { die(format!( "value for define '{arg}' must be a valid 8-bit integer" )); - return (String::default(), 0); } }; @@ -189,7 +187,7 @@ fn parse_arguments() -> Args { } // Print the given `message` and exit(1). -fn die(message: String) { +fn die(message: String) -> ! { eprintln!("error: {message}"); std::process::exit(1); } @@ -222,7 +220,7 @@ fn get_directory_from_source(source: &SourceInfo) -> PathBuf { // Save the `memory` object into the `/.nasm/memory.txt` file. fn save_memory_stats(source: &SourceInfo, memory: &mut MemoryResult, has_working_ram: bool) { let Ok(mut file) = File::create(get_directory_from_source(source).join("memory.txt")) else { - return die("could not write memory.txt file".to_string()); + die("could not write memory.txt file".to_string()); }; let ranges = &mut memory.memory_ranges; @@ -231,15 +229,15 @@ fn save_memory_stats(source: &SourceInfo, memory: &mut MemoryResult, has_working for mr in ranges { if mr.range.start + 1 == mr.range.end { if let Err(e) = writeln!(file, "{}: {}", mr.to_human(), mr.name) { - return die(format!("could not write memory.txt file: {e}")); + die(format!("could not write memory.txt file: {e}")); } } else if let Err(e) = writeln!(file, "{}: {}", mr.to_human(), mr.name) { - return die(format!("could not write memory.txt file: {e}")); + die(format!("could not write memory.txt file: {e}")); } } if let Err(e) = writeln!(file, "\n--- Summary (in bytes) ---") { - return die(format!("could not write memory.txt file: {e}")); + die(format!("could not write memory.txt file: {e}")); } print_memory_summary(Box::new(file), memory, has_working_ram); } @@ -255,7 +253,7 @@ fn print_memory_summary(mut output: Box, memory: &MemoryResult, has_w "- Internal RAM: {}/2048 ({:.2}%)", memory.total_internal_ram, perc ) { - return die(format!("could not write memory summary: {e}")); + die(format!("could not write memory summary: {e}")); } if has_working_ram { @@ -273,13 +271,13 @@ fn print_memory_summary(mut output: Box, memory: &MemoryResult, has_w // Save the 'addresses' list into the `/.nasm/addresses.txt` file. fn save_addresses(source: &SourceInfo, mut addresses: Vec) { let Ok(mut file) = File::create(get_directory_from_source(source).join("addresses.txt")) else { - return die("could not write memory.txt file".to_string()); + die("could not write memory.txt file".to_string()); }; addresses.sort_by_key(|a| a.range.start); for a in addresses { if let Err(e) = writeln!(file, "{},{:04X},{:04X}", a.name, a.range.start, a.range.end) { - return die(format!("could not write addresses.txt file: {e}")); + die(format!("could not write addresses.txt file: {e}")); } } } @@ -296,14 +294,14 @@ fn print_segments_stats(mut output: Box, mappings: &[Mapping]) { "- {}: {}/{} ({:.0}%)", mapping.name, mapping.offset, mapping.size, perc ) { - return die(format!("could not write segments summary: {e}")); + die(format!("could not write segments summary: {e}")); } } else if let Err(e) = writeln!( output, "- {}: {}/{} ({:.2}%)", mapping.name, mapping.offset, mapping.size, perc ) { - return die(format!("could not write segments summary: {e}")); + die(format!("could not write segments summary: {e}")); } } } @@ -315,17 +313,13 @@ fn main() { let path = Path::new(&args.file); let Ok(input) = File::open(path) else { die(format!("failed to open the given file '{}'", args.file)); - return; }; let source = match path.parent() { Some(parent) => SourceInfo { directory: parent.to_path_buf(), name: path.file_name().unwrap().to_str().unwrap().to_string(), }, - None => { - die("failed to find directory for the given file".to_string()); - return; - } + None => die("failed to find directory for the given file".to_string()), }; // Select the output stream. @@ -337,10 +331,7 @@ fn main() { let name = args.out.unwrap_or(String::from("out.nes")); match File::create(&name) { Ok(f) => (BufWriter::new(Box::new(f)), args.file.as_str()), - Err(_) => { - die(format!("could not create file '{name}'")); - return; - } + Err(_) => die(format!("could not create file '{name}'")), } }; @@ -455,7 +446,7 @@ fn main() { if args.info { let Ok(file) = File::create(get_directory_from_source(&source).join("segments.txt")) else { - return die("could not write segments.txt file".to_string()); + die("could not write segments.txt file".to_string()); }; print_segments_stats(Box::new(file), &res.mappings); } diff --git a/crates/readrom/src/main.rs b/crates/readrom/src/main.rs index ef7fa9b..8d70e16 100644 --- a/crates/readrom/src/main.rs +++ b/crates/readrom/src/main.rs @@ -175,7 +175,7 @@ fn print_vectors(addrs: &[u8]) { } // Print the given `message` and exit(1). -fn die(message: String) { +fn die(message: String) -> ! { println!("error: {message}"); std::process::exit(1); } @@ -527,7 +527,6 @@ fn main() { // Open the ROM file and read it. let Ok(mut input) = File::open(&args.file) else { die(format!("failed to open the given file '{}'", args.file)); - return; }; let mut bytes = Vec::new(); if let Err(e) = input.read_to_end(&mut bytes) { @@ -553,10 +552,7 @@ fn main() { let header = match Header::try_from(buf) { Ok(h) => h, - Err(e) => { - die(e.to_string()); - return; - } + Err(e) => die(e.to_string()), }; print_header(&header); diff --git a/crates/runrom/src/main.rs b/crates/runrom/src/main.rs index ab1ea83..1535c94 100644 --- a/crates/runrom/src/main.rs +++ b/crates/runrom/src/main.rs @@ -27,7 +27,7 @@ fn print_help() { } // Print the given `message` and exit(1). -fn die(message: String) { +fn die(message: String) -> ! { eprintln!("error: {message}"); std::process::exit(1); } @@ -123,7 +123,6 @@ fn start_from_reset_vector(file: &String) -> u16 { let Ok(mut input) = File::open(file) else { die(format!("failed to open the given file '{file}'")); - return 0; }; let mut buf = vec![0u8; 0x10]; @@ -136,10 +135,7 @@ fn start_from_reset_vector(file: &String) -> u16 { let header = match Header::try_from(buf.as_slice()) { Ok(h) => h, - Err(e) => { - die(e.to_string()); - return 0; - } + Err(e) => die(e.to_string()), }; // 2. With a known PRG ROM size, fetch the two bytes pertaining to the reset @@ -155,7 +151,6 @@ fn start_from_reset_vector(file: &String) -> u16 { if input.seek(SeekFrom::Start(offset)).is_err() { die("cannot peek into the ROM's reset address".to_string()); - return 0; }; let mut buf = [0u8; 0x02]; if let Err(e) = input.read_exact(&mut buf) { diff --git a/crates/xa65/src/main.rs b/crates/xa65/src/main.rs index 03bdc82..a717ddb 100644 --- a/crates/xa65/src/main.rs +++ b/crates/xa65/src/main.rs @@ -28,11 +28,15 @@ fn print_help() { println!("Options:"); println!(" --allow-unused\tPass the '--allow-unused' flag to 'nasm'."); println!(" -b, --bin \tAlternative to the binary for 'nasm'."); - println!(" -C, --config \tLinker configuration to be used, whether an identifier or a file path."); + println!( + " -C, --config \tLinker configuration to be used, whether an identifier or a file path." + ); println!(" -h, --help\t\tPrint this message."); println!(" -n, --no-errors\tError out if the output differ or 'nasm' has produced an error."); println!(" -o, --out \tFile path where the output should be located after execution."); - println!(" -s, --strict\t\tBe more strict on 'nasm' by adding the address-sanitizer and writing debug/analysis information."); + println!( + " -s, --strict\t\tBe more strict on 'nasm' by adding the address-sanitizer and writing debug/analysis information." + ); println!(" --stats\t\tPrint statistics to the standard output."); println!(" --target nes\t\tUsed for compatibility with 'ca65'."); println!(" -v, --version\t\tPrint the version of this program."); @@ -123,7 +127,7 @@ fn parse_arguments() -> Args { } // Print the given `message` and exit(1). -fn die(message: String) { +fn die(message: String) -> ! { eprintln!("error: {message}"); std::process::exit(1); } @@ -234,10 +238,7 @@ fn main() { // Make sure that the binaries are there. let (nasm, cl65) = match get_binaries(args.bin.unwrap_or("nasm".to_string())) { Ok((nasm, cl65)) => (nasm, cl65), - Err(e) => { - die(e); - return; - } + Err(e) => die(e), }; // Generate a temporary directory in which both binary files will be placed @@ -245,7 +246,6 @@ fn main() { let dir = temporary_dir(); if let Err(e) = std::fs::create_dir(&dir) { die(format!("could not create temporary directory: {}", e)); - return; } // Run 'nasm' with the given arguments. We only care about the exit code of @@ -277,10 +277,7 @@ fn main() { std::process::exit(cmd.code().unwrap_or(1)); } } - Err(e) => { - die(e.to_string()); - return; - } + Err(e) => die(e.to_string()), } // Run 'cl65' with the given arguments. @@ -303,10 +300,7 @@ fn main() { std::process::exit(1); } } - Err(e) => { - die(e.to_string()); - return; - } + Err(e) => die(e.to_string()), } // Everything went fine, we should have both binaries available to be @@ -335,10 +329,7 @@ fn main() { } } } - Err(e) => { - die(e.to_string()); - return; - } + Err(e) => die(e.to_string()), } // And just copy one of the binaries to where it was originally requested. -- cgit v1.2.3