From ce7c4bfb521404ebe6576d045763c0181b763a61 Mon Sep 17 00:00:00 2001 From: sofia Date: Thu, 17 Jul 2025 17:15:47 +0300 Subject: [PATCH] Improve error raporting futher significantly --- Cargo.lock | 83 +++++++++++++++++++++++++++++++++++++ reid/Cargo.toml | 10 ++++- reid/src/error_raporting.rs | 51 ++++++++++++++++++----- reid/src/lib.rs | 38 ++++++++--------- reid/src/mir/mod.rs | 7 ++++ reid/src/mir/pass.rs | 8 +++- reid_src/array_structs.reid | 6 +-- 7 files changed, 169 insertions(+), 34 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index bcedbb9..98d2095 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,15 @@ version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" +[[package]] +name = "colored" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" +dependencies = [ + "windows-sys", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -99,6 +108,7 @@ checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2" name = "reid" version = "0.1.0" dependencies = [ + "colored", "llvm-sys", "reid-lib", "thiserror", @@ -154,3 +164,76 @@ name = "unicode-ident" version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/reid/Cargo.toml b/reid/Cargo.toml index 36a2c7c..afa4fde 100644 --- a/reid/Cargo.toml +++ b/reid/Cargo.toml @@ -5,9 +5,17 @@ edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[features] +default = ["color"] + +color = ["colored"] + [dependencies] ## LLVM Bindings llvm-sys = "160" ## Make it easier to generate errors thiserror = "1.0.44" -reid-lib = { path = "../reid-llvm-lib" } \ No newline at end of file +reid-lib = { path = "../reid-llvm-lib" } + +colored = {version = "3.0.0", optional = true} \ No newline at end of file diff --git a/reid/src/error_raporting.rs b/reid/src/error_raporting.rs index 39b80d9..bf20403 100644 --- a/reid/src/error_raporting.rs +++ b/reid/src/error_raporting.rs @@ -1,4 +1,7 @@ -use std::{collections::HashMap, fmt::Debug}; +use std::{ + collections::HashMap, + fmt::{Debug, Write}, +}; use crate::{ ast, lexer, @@ -14,15 +17,15 @@ impl pass::Error { #[derive(thiserror::Error, Debug, Clone, PartialEq, Eq)] pub enum ErrorKind { - #[error("Lexing: {0:?}")] + #[error("Lexing: {}", .0.kind)] LexerError(#[from] mir::pass::Error), - #[error("Parsing: {0:?}")] + #[error("Parsing: {}", .0.kind)] ParserError(#[from] mir::pass::Error), - #[error("Typechecking: {0:?}")] + #[error("Typechecking: {}", .0.kind)] TypeCheckError(#[source] mir::pass::Error), - #[error("Type Inference: {0:?}")] + #[error("Type Inference: {}", .0.kind)] TypeInferenceError(#[source] mir::pass::Error), - #[error("Linking: {0:?}")] + #[error("Linking: {}", .0.kind)] LinkerError(#[from] mir::pass::Error), } @@ -106,6 +109,7 @@ impl std::fmt::Display for ReidError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let mut sorted_errors = self.errors.clone(); sorted_errors.sort_by(|a, b| a.cmp(&b)); + sorted_errors.dedup(); let mut curr_module = None; for error in sorted_errors { @@ -115,12 +119,15 @@ impl std::fmt::Display for ReidError { writeln!( f, "Errors in module {}:", - self.map.module_map.get(&meta.source_module_id).unwrap() + color_err(format!( + "{}", + self.map.module_map.get(&meta.source_module_id).unwrap() + ))? )?; } - write!(f, " Error: ")?; - std::fmt::Display::fmt(&error, f)?; - writeln!(f, " At: {}", meta)?; + write!(f, " {}: ", color_err("Error")?)?; + writeln!(f, "{}", error)?; + writeln!(f, " {}: {}", color_warn("At")?, meta)?; } Ok(()) } @@ -173,3 +180,27 @@ impl ReidError { ReidError { map, errors } } } + +fn color_err(elem: impl std::fmt::Display) -> Result { + let mut text = format!("{}", elem); + + #[cfg(feature = "color")] + { + use colored::Colorize; + text = format!("{}", text.bright_red()) + } + + Ok(text) +} + +fn color_warn(elem: impl std::fmt::Display) -> Result { + let mut text = format!("{}", elem); + + #[cfg(feature = "color")] + { + use colored::Colorize; + text = format!("{}", text.bright_yellow()) + } + + Ok(text) +} diff --git a/reid/src/lib.rs b/reid/src/lib.rs index 088043c..12ff029 100644 --- a/reid/src/lib.rs +++ b/reid/src/lib.rs @@ -124,6 +124,8 @@ pub fn perform_all_passes<'map>( let refs = TypeRefs::default(); + let mut errors = Vec::new(); + let state = context.pass(&mut TypeInference { refs: &refs }); #[cfg(debug_assertions)] @@ -133,16 +135,13 @@ pub fn perform_all_passes<'map>( #[cfg(debug_assertions)] dbg!(&state); - if !state.errors.is_empty() { - return Err(ReidError::from_kind::<()>( - state - .errors - .iter() - .map(|e| ErrorRapKind::TypeInferenceError(e.clone())) - .collect(), - map.clone(), - )); - } + errors.extend( + state + .errors + .iter() + .map(|e| ErrorRapKind::TypeInferenceError(e.clone())) + .collect::>(), + ); let state = context.pass(&mut TypeCheck { refs: &refs }); @@ -151,15 +150,16 @@ pub fn perform_all_passes<'map>( #[cfg(debug_assertions)] dbg!(&state); - if !state.errors.is_empty() { - return Err(ReidError::from_kind::<()>( - state - .errors - .iter() - .map(|e| ErrorRapKind::TypeCheckError(e.clone())) - .collect(), - map.clone(), - )); + errors.extend( + state + .errors + .iter() + .map(|e| ErrorRapKind::TypeInferenceError(e.clone())) + .collect::>(), + ); + + if !errors.is_empty() { + return Err(ReidError::from_kind::<()>(errors, map.clone())); } Ok(()) diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index da69650..7294a1b 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -31,6 +31,13 @@ pub struct Metadata { pub position: Option, } +impl Metadata { + pub fn complete_overlap(&self, other: &Metadata) -> bool { + (self.range.start >= other.range.start && self.range.end <= other.range.end) + || (other.range.start >= self.range.start && other.range.end <= self.range.end) + } +} + impl std::ops::Add for Metadata { type Output = Metadata; diff --git a/reid/src/mir/pass.rs b/reid/src/mir/pass.rs index 4e79d34..65a99d1 100644 --- a/reid/src/mir/pass.rs +++ b/reid/src/mir/pass.rs @@ -15,7 +15,7 @@ pub enum SimplePassError { VariableAlreadyDefined(String), } -#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] +#[derive(Debug, Clone, Eq, PartialOrd, Ord)] pub struct Error { pub metadata: Metadata, pub kind: TErr, @@ -33,6 +33,12 @@ impl STDError for Error { } } +impl PartialEq for Error { + fn eq(&self, other: &Self) -> bool { + self.kind == other.kind && self.metadata.complete_overlap(&other.metadata) + } +} + #[derive(Debug)] pub struct State { pub errors: Vec>, diff --git a/reid_src/array_structs.reid b/reid_src/array_structs.reid index 4dafe3f..ec2d412 100644 --- a/reid_src/array_structs.reid +++ b/reid_src/array_structs.reid @@ -8,7 +8,7 @@ struct Test { fn main() -> u32 { let mut value = [Test { field: 5, - second: [6, 3, 17, 8], + second: [6, 3, "hello", 8], }]; let val1 = 0; @@ -16,8 +16,8 @@ fn main() -> u32 { // value[val1].second[val2 + 1] = 99; - let mut b = value[val1]; + let mut b = valude[val1]; b.second[2] = 99; - return value[val1].second[2]; + return value[val1].sezcond[2]; }