Improve error raporting futher significantly
This commit is contained in:
		
							parent
							
								
									f0e47a5d57
								
							
						
					
					
						commit
						ce7c4bfb52
					
				
							
								
								
									
										83
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										83
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @ -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" | ||||
|  | ||||
| @ -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} | ||||
| @ -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) | ||||
| } | ||||
|  | ||||
| @ -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(()) | ||||
|  | ||||
| @ -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; | ||||
| 
 | ||||
|  | ||||
| @ -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>>, | ||||
|  | ||||
| @ -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]; | ||||
| } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user