Improve error raporting futher significantly

This commit is contained in:
Sofia 2025-07-17 17:15:47 +03:00
parent f0e47a5d57
commit ce7c4bfb52
7 changed files with 169 additions and 34 deletions

83
Cargo.lock generated
View File

@ -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"

View File

@ -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" }
reid-lib = { path = "../reid-llvm-lib" }
colored = {version = "3.0.0", optional = true}

View File

@ -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<T: std::error::Error + std::fmt::Display> pass::Error<T> {
#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq)]
pub enum ErrorKind {
#[error("Lexing: {0:?}")]
#[error("Lexing: {}", .0.kind)]
LexerError(#[from] mir::pass::Error<lexer::Error>),
#[error("Parsing: {0:?}")]
#[error("Parsing: {}", .0.kind)]
ParserError(#[from] mir::pass::Error<token_stream::Error>),
#[error("Typechecking: {0:?}")]
#[error("Typechecking: {}", .0.kind)]
TypeCheckError(#[source] mir::pass::Error<mir::typecheck::ErrorKind>),
#[error("Type Inference: {0:?}")]
#[error("Type Inference: {}", .0.kind)]
TypeInferenceError(#[source] mir::pass::Error<mir::typecheck::ErrorKind>),
#[error("Linking: {0:?}")]
#[error("Linking: {}", .0.kind)]
LinkerError(#[from] mir::pass::Error<mir::linker::ErrorKind>),
}
@ -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<String, std::fmt::Error> {
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<String, std::fmt::Error> {
let mut text = format!("{}", elem);
#[cfg(feature = "color")]
{
use colored::Colorize;
text = format!("{}", text.bright_yellow())
}
Ok(text)
}

View File

@ -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::<Vec<_>>(),
);
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::<Vec<_>>(),
);
if !errors.is_empty() {
return Err(ReidError::from_kind::<()>(errors, map.clone()));
}
Ok(())

View File

@ -31,6 +31,13 @@ pub struct Metadata {
pub position: Option<Position>,
}
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;

View File

@ -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<TErr: STDError> {
pub metadata: Metadata,
pub kind: TErr,
@ -33,6 +33,12 @@ impl<TErr: STDError> STDError for Error<TErr> {
}
}
impl<TErr: STDError + PartialEq> PartialEq for Error<TErr> {
fn eq(&self, other: &Self) -> bool {
self.kind == other.kind && self.metadata.complete_overlap(&other.metadata)
}
}
#[derive(Debug)]
pub struct State<TErr: STDError> {
pub errors: Vec<Error<TErr>>,

View File

@ -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];
}