diff --git a/reid/examples/cli.rs b/reid/examples/cli.rs index 4231410..9d7a9d8 100644 --- a/reid/examples/cli.rs +++ b/reid/examples/cli.rs @@ -1,6 +1,6 @@ -use std::{env, error::Error, fs, path::PathBuf}; +use std::{env, fs, path::PathBuf}; -use reid::compile; +use reid::compile_simple; use reid_lib::compile::CompileOutput; fn main() -> Result<(), std::io::Error> { @@ -15,7 +15,7 @@ fn main() -> Result<(), std::io::Error> { let before = std::time::SystemTime::now(); let text = fs::read_to_string(&path)?; - match compile(&text, PathBuf::from(&path)) { + match compile_simple(&text, PathBuf::from(&path)) { Ok(CompileOutput { triple, assembly, diff --git a/reid/src/error_raporting.rs b/reid/src/error_raporting.rs index e69de29..39b80d9 100644 --- a/reid/src/error_raporting.rs +++ b/reid/src/error_raporting.rs @@ -0,0 +1,175 @@ +use std::{collections::HashMap, fmt::Debug}; + +use crate::{ + ast, lexer, + mir::{self, pass, Metadata, SourceModuleId}, + token_stream, +}; + +impl pass::Error { + fn fmt_simple(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + std::fmt::Display::fmt(&self.kind, f) + } +} + +#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq)] +pub enum ErrorKind { + #[error("Lexing: {0:?}")] + LexerError(#[from] mir::pass::Error), + #[error("Parsing: {0:?}")] + ParserError(#[from] mir::pass::Error), + #[error("Typechecking: {0:?}")] + TypeCheckError(#[source] mir::pass::Error), + #[error("Type Inference: {0:?}")] + TypeInferenceError(#[source] mir::pass::Error), + #[error("Linking: {0:?}")] + LinkerError(#[from] mir::pass::Error), +} + +impl ErrorKind { + pub fn from_typecheck(err: mir::pass::Error) -> ErrorKind { + ErrorKind::TypeCheckError(err) + } + + pub fn from_typeinference(err: mir::pass::Error) -> ErrorKind { + ErrorKind::TypeInferenceError(err) + } +} + +impl ErrorKind { + fn get_meta(&self) -> Metadata { + match &self { + ErrorKind::LexerError(error) => error.metadata, + ErrorKind::ParserError(error) => error.metadata, + ErrorKind::TypeCheckError(error) => error.metadata, + ErrorKind::TypeInferenceError(error) => error.metadata, + ErrorKind::LinkerError(error) => error.metadata, + } + } +} + +impl PartialOrd for ErrorKind { + fn partial_cmp(&self, other: &Self) -> Option { + self.get_meta() + .source_module_id + .partial_cmp(&other.get_meta().source_module_id) + } +} + +impl Ord for ErrorKind { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.get_meta().cmp(&other.get_meta()) + } +} + +#[derive(Debug, Clone, PartialEq, Eq, Default)] +pub struct ModuleMap { + module_map: HashMap, + module_counter: mir::SourceModuleId, +} + +impl ModuleMap { + pub fn add_module>(&mut self, name: T) -> Option { + let id = self.module_counter.increment(); + self.module_map.insert(id, name.into().clone()); + Some(id) + } +} + +impl TryFrom<&mir::Context> for ModuleMap { + type Error = (); + + fn try_from(value: &mir::Context) -> Result { + let mut map = HashMap::new(); + for module in &value.modules { + if let Some(_) = map.insert(module.module_id, module.name.clone()) { + return Err(()); + } + } + let module_counter = value.modules.iter().map(|m| m.module_id).max().ok_or(())?; + Ok(ModuleMap { + module_map: map, + module_counter, + }) + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct ReidError { + map: ModuleMap, + errors: Vec, +} + +impl std::error::Error for ReidError {} + +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)); + + let mut curr_module = None; + for error in sorted_errors { + let meta = error.get_meta(); + if curr_module != Some(meta.source_module_id) { + curr_module = Some(meta.source_module_id); + writeln!( + f, + "Errors in module {}:", + self.map.module_map.get(&meta.source_module_id).unwrap() + )?; + } + write!(f, " Error: ")?; + std::fmt::Display::fmt(&error, f)?; + writeln!(f, " At: {}", meta)?; + } + Ok(()) + } +} + +impl ReidError { + pub fn from_lexer( + result: Result, + map: ModuleMap, + module: SourceModuleId, + ) -> Result { + result.map_err(|error| { + let pass_err = pass::Error { + metadata: Metadata { + source_module_id: module, + range: Default::default(), + position: Some(*error.get_position()), + }, + kind: error, + }; + ReidError { + map, + errors: vec![ErrorKind::LexerError(pass_err)], + } + }) + } + + pub fn from_parser( + result: Result, + map: ModuleMap, + module: SourceModuleId, + ) -> Result { + result.map_err(|error| { + let pass_err = pass::Error { + metadata: Metadata { + source_module_id: module, + range: Default::default(), + position: error.get_position().copied(), + }, + kind: error, + }; + ReidError { + map, + errors: vec![ErrorKind::ParserError(pass_err)], + } + }) + } + + pub fn from_kind(errors: Vec, map: ModuleMap) -> ReidError { + ReidError { map, errors } + } +} diff --git a/reid/src/lexer.rs b/reid/src/lexer.rs index e72cba8..ba72a08 100644 --- a/reid/src/lexer.rs +++ b/reid/src/lexer.rs @@ -2,7 +2,7 @@ use std::{fmt::Debug, str::Chars}; static DECIMAL_NUMERICS: &[char] = &['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']; -#[derive(Debug, Eq, PartialEq, Clone)] +#[derive(Debug, Eq, PartialEq, Clone, PartialOrd, Ord)] pub enum Token { /// Values Identifier(String), @@ -273,10 +273,19 @@ pub fn tokenize>(to_tokenize: T) -> Result, Error Ok(tokens) } -#[derive(thiserror::Error, Debug, Clone)] +#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum Error { #[error("Invalid token '{}' at Ln {}, Col {}", .0, (.1).1, (.1).0)] InvalidToken(char, Position), #[error("String literal that starts at Ln {}, Col {} is never finished!", (.0).1, (.0).0)] MissingQuotation(Position), } + +impl Error { + pub fn get_position(&self) -> &Position { + match self { + Error::InvalidToken(_, pos) => pos, + Error::MissingQuotation(pos) => pos, + } + } +} diff --git a/reid/src/lib.rs b/reid/src/lib.rs index ae7f1ae..088043c 100644 --- a/reid/src/lib.rs +++ b/reid/src/lib.rs @@ -41,8 +41,9 @@ //! - Debug Symbols //! ``` -use std::path::PathBuf; +use std::{convert::Infallible, path::PathBuf}; +use error_raporting::{ErrorKind as ErrorRapKind, ModuleMap, ReidError}; use mir::{ linker::LinkerPass, typecheck::TypeCheck, typeinference::TypeInference, typerefs::TypeRefs, SourceModuleId, @@ -53,34 +54,22 @@ use crate::{ast::TopLevelStatement, lexer::Token, token_stream::TokenStream}; mod ast; mod codegen; +mod error_raporting; mod lexer; pub mod mir; mod pad_adapter; mod token_stream; mod util; -#[derive(thiserror::Error, Debug, Clone)] -pub enum ReidError { - #[error(transparent)] - LexerError(#[from] lexer::Error), - #[error(transparent)] - ParserError(#[from] token_stream::Error), - #[error("Errors during typecheck: {0:?}")] - TypeCheckErrors(Vec>), - #[error("Errors during type inference: {0:?}")] - TypeInferenceErrors(Vec>), - #[error("Errors during linking: {0:?}")] - LinkerErrors(Vec>), -} - -pub fn compile_module( +pub fn compile_module<'map>( source: &str, name: String, - module_id: SourceModuleId, + map: &'map mut ModuleMap, path: Option, is_main: bool, ) -> Result { - let tokens = lexer::tokenize(source)?; + let id = map.add_module(name.clone()).unwrap(); + let tokens = ReidError::from_lexer(lexer::tokenize(source), map.clone(), id)?; #[cfg(debug_assertions)] dbg!(&tokens); @@ -90,7 +79,8 @@ pub fn compile_module( let mut statements = Vec::new(); while !matches!(token_stream.peek().unwrap_or(Token::Eof), Token::Eof) { - let statement = token_stream.parse::()?; + let statement = + ReidError::from_parser(token_stream.parse::(), map.clone(), id)?; statements.push(statement); } @@ -101,17 +91,24 @@ pub fn compile_module( is_main, }; - Ok(ast_module.process(module_id)) + Ok(ast_module.process(id)) } -pub fn perform_all_passes(context: &mut mir::Context) -> Result<(), ReidError> { +pub fn perform_all_passes<'map>( + context: &mut mir::Context, + map: &'map mut ModuleMap, +) -> Result<(), ReidError> { #[cfg(debug_assertions)] dbg!(&context); #[cfg(debug_assertions)] println!("{}", &context); - let state = context.pass(&mut LinkerPass); + let mut module_map = (&*context).try_into().unwrap(); + + let state = context.pass(&mut LinkerPass { + module_map: &mut module_map, + }); #[cfg(debug_assertions)] println!("{}", &context); @@ -119,7 +116,10 @@ pub fn perform_all_passes(context: &mut mir::Context) -> Result<(), ReidError> { dbg!(&state); if !state.errors.is_empty() { - return Err(ReidError::LinkerErrors(state.errors)); + return Err(ReidError::from_kind::<()>( + state.errors.iter().map(|e| e.clone().into()).collect(), + map.clone(), + )); } let refs = TypeRefs::default(); @@ -134,7 +134,14 @@ pub fn perform_all_passes(context: &mut mir::Context) -> Result<(), ReidError> { dbg!(&state); if !state.errors.is_empty() { - return Err(ReidError::TypeInferenceErrors(state.errors)); + return Err(ReidError::from_kind::<()>( + state + .errors + .iter() + .map(|e| ErrorRapKind::TypeInferenceError(e.clone())) + .collect(), + map.clone(), + )); } let state = context.pass(&mut TypeCheck { refs: &refs }); @@ -145,7 +152,14 @@ pub fn perform_all_passes(context: &mut mir::Context) -> Result<(), ReidError> { dbg!(&state); if !state.errors.is_empty() { - return Err(ReidError::TypeCheckErrors(state.errors)); + return Err(ReidError::from_kind::<()>( + state + .errors + .iter() + .map(|e| ErrorRapKind::TypeCheckError(e.clone())) + .collect(), + map.clone(), + )); } Ok(()) @@ -154,21 +168,24 @@ pub fn perform_all_passes(context: &mut mir::Context) -> Result<(), ReidError> { /// Takes in a bit of source code, parses and compiles it and produces `hello.o` /// and `hello.asm` from it, which can be linked using `ld` to produce an /// executable file. -pub fn compile(source: &str, path: PathBuf) -> Result { +pub fn compile_and_pass<'map>( + source: &str, + path: PathBuf, + module_map: &'map mut ModuleMap, +) -> Result { let path = path.canonicalize().unwrap(); - let mut mir_context = mir::Context::from( - vec![compile_module( - source, - path.file_name().unwrap().to_str().unwrap().to_owned(), - SourceModuleId::default(), - Some(path.clone()), - true, - )?], - path.parent().unwrap().to_owned(), - ); + let module = compile_module( + source, + path.file_name().unwrap().to_str().unwrap().to_owned(), + module_map, + Some(path.clone()), + true, + )?; - perform_all_passes(&mut mir_context)?; + let mut mir_context = mir::Context::from(vec![module], path.parent().unwrap().to_owned()); + + perform_all_passes(&mut mir_context, module_map)?; let mut context = Context::new(); let codegen_modules = mir_context.codegen(&mut context); @@ -179,3 +196,8 @@ pub fn compile(source: &str, path: PathBuf) -> Result let compiled = codegen_modules.compile(); Ok(compiled.output()) } + +pub fn compile_simple(source: &str, path: PathBuf) -> Result { + let mut map = ModuleMap::default(); + compile_and_pass(source, path, &mut map) +} diff --git a/reid/src/mir/impl.rs b/reid/src/mir/impl.rs index e175b68..2624bac 100644 --- a/reid/src/mir/impl.rs +++ b/reid/src/mir/impl.rs @@ -279,7 +279,7 @@ impl TypeKind { } } -#[derive(Debug, Clone, thiserror::Error)] +#[derive(Debug, Clone, thiserror::Error, PartialEq, Eq, PartialOrd, Ord)] pub enum EqualsIssue { #[error("Function is already defined locally at {:?}", (.0).range)] ExistsLocally(Metadata), diff --git a/reid/src/mir/linker.rs b/reid/src/mir/linker.rs index 82fc776..b5c7e27 100644 --- a/reid/src/mir/linker.rs +++ b/reid/src/mir/linker.rs @@ -7,7 +7,7 @@ use std::{ rc::Rc, }; -use crate::{compile_module, ReidError}; +use crate::{compile_module, error_raporting::ModuleMap}; use super::{ pass::{Pass, PassState}, @@ -17,14 +17,14 @@ use super::{ pub static STD_SOURCE: &str = include_str!("../../lib/std.reid"); -#[derive(thiserror::Error, Debug, Clone)] +#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum ErrorKind { #[error("Unable to import inner modules, not yet supported: {0}")] InnerModulesNotYetSupported(Import), #[error("No such module: {0}")] ModuleNotFound(String), #[error("Error while compiling module {0}: {1}")] - ModuleCompilationError(String, ReidError), + ModuleCompilationError(String, String), #[error("No such function {0} found in module {1}")] NoSuchFunctionInModule(String, String), #[error("Importing function {0}::{1} not possible: {2}")] @@ -41,11 +41,11 @@ pub enum ErrorKind { FunctionIsPrivate(String, String), } -pub fn compile_std(module_id: SourceModuleId) -> super::Module { +pub fn compile_std(module_map: &mut ModuleMap) -> super::Module { let module = compile_module( STD_SOURCE, "standard_library".to_owned(), - module_id, + module_map, None, false, ) @@ -59,11 +59,13 @@ pub fn compile_std(module_id: SourceModuleId) -> super::Module { /// Struct used to implement a type-checking pass that can be performed on the /// MIR. -pub struct LinkerPass; +pub struct LinkerPass<'map> { + pub module_map: &'map mut ModuleMap, +} type LinkerPassState<'st, 'sc> = PassState<'st, 'sc, (), ErrorKind>; -impl Pass for LinkerPass { +impl<'map> Pass for LinkerPass<'map> { type Data = (); type TError = ErrorKind; fn context(&mut self, context: &mut Context, mut state: LinkerPassState) { @@ -92,15 +94,9 @@ impl Pass for LinkerPass { modules.insert(module.name.clone(), Rc::new(RefCell::new(module))); } - let mut module_counter = modules - .values() - .map(|m| m.borrow().module_id) - .max() - .unwrap(); - modules.insert( "std".to_owned(), - Rc::new(RefCell::new(compile_std(module_counter.increment()))), + Rc::new(RefCell::new(compile_std(&mut self.module_map))), ); let mut modules_to_process: Vec>> = modules.values().cloned().collect(); @@ -136,7 +132,7 @@ impl Pass for LinkerPass { match compile_module( &source, module_name.clone(), - module_counter.increment(), + &mut self.module_map, Some(file_path), false, ) { @@ -159,7 +155,10 @@ impl Pass for LinkerPass { } Err(err) => { state.ok::<_, Infallible>( - Err(ErrorKind::ModuleCompilationError(module_name.clone(), err)), + Err(ErrorKind::ModuleCompilationError( + module_name.clone(), + format!("{}", err), + )), import.1, ); continue; diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index be9968a..da69650 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -4,7 +4,7 @@ use std::{collections::HashMap, path::PathBuf}; -use crate::token_stream::TokenRange; +use crate::{lexer::Position, token_stream::TokenRange}; mod display; pub mod r#impl; @@ -24,10 +24,11 @@ impl SourceModuleId { } } -#[derive(Debug, Default, Clone, Copy)] +#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct Metadata { - pub range: TokenRange, pub source_module_id: SourceModuleId, + pub range: TokenRange, + pub position: Option, } impl std::ops::Add for Metadata { @@ -38,6 +39,7 @@ impl std::ops::Add for Metadata { Metadata { range: self.range + rhs.range, source_module_id: self.source_module_id, + position: None, } } } @@ -47,11 +49,12 @@ impl TokenRange { Metadata { range: self, source_module_id: module, + position: None, } } } -#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)] +#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error, PartialOrd, Ord)] pub enum TypeKind { #[error("bool")] Bool, @@ -89,7 +92,7 @@ pub enum TypeKind { Vague(#[from] VagueType), } -#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error, PartialOrd, Ord)] pub enum VagueType { #[error("Unknown")] Unknown, @@ -125,7 +128,7 @@ impl TypeKind { } } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum Literal { I8(i8), I16(i16), @@ -142,7 +145,7 @@ pub enum Literal { Vague(VagueLiteral), } -#[derive(Debug, Clone, Copy)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub enum VagueLiteral { Number(u64), } @@ -204,7 +207,7 @@ pub enum ReturnKind { #[derive(Debug)] pub struct NamedVariableRef(pub TypeKind, pub String, pub Metadata); -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct Import(pub Vec, pub Metadata); #[derive(Debug)] diff --git a/reid/src/mir/pass.rs b/reid/src/mir/pass.rs index 3706015..4e79d34 100644 --- a/reid/src/mir/pass.rs +++ b/reid/src/mir/pass.rs @@ -15,10 +15,10 @@ pub enum SimplePassError { VariableAlreadyDefined(String), } -#[derive(Debug, Clone)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub struct Error { - metadata: Metadata, - kind: TErr, + pub metadata: Metadata, + pub kind: TErr, } impl std::fmt::Display for Error { diff --git a/reid/src/mir/typecheck.rs b/reid/src/mir/typecheck.rs index c39fcf2..45bf672 100644 --- a/reid/src/mir/typecheck.rs +++ b/reid/src/mir/typecheck.rs @@ -10,7 +10,7 @@ use super::{ typerefs::TypeRefs, }; -#[derive(thiserror::Error, Debug, Clone)] +#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum ErrorKind { #[error("NULL error, should never occur!")] Null, diff --git a/reid/src/token_stream.rs b/reid/src/token_stream.rs index 824f521..afc663b 100644 --- a/reid/src/token_stream.rs +++ b/reid/src/token_stream.rs @@ -174,7 +174,7 @@ impl Drop for TokenStream<'_, '_> { /// Index-range that can be used with the original array of [`FullToken`]s to /// retrieve the precise location of a failure. -#[derive(Default, Clone, Copy)] +#[derive(Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] pub struct TokenRange { pub start: usize, pub end: usize, @@ -207,7 +207,7 @@ impl std::iter::Sum for TokenRange { } } -#[derive(thiserror::Error, Debug, Clone)] +#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)] pub enum Error { #[error("Expected {} at Ln {}, Col {}, got {:?}", .0, (.2).1, (.2).0, .1)] Expected(String, Token, Position), @@ -220,3 +220,14 @@ pub enum Error { #[error("Condition failed for parse-if. Should never be returned to end-user.")] IfFailed, } + +impl Error { + pub fn get_position(&self) -> Option<&Position> { + match self { + Error::Expected(_, _, pos) => Some(pos), + Error::FileEmpty => None, + Error::Undefined => None, + Error::IfFailed => None, + } + } +} diff --git a/reid/tests/e2e.rs b/reid/tests/e2e.rs index 7cc5713..d9475f3 100644 --- a/reid/tests/e2e.rs +++ b/reid/tests/e2e.rs @@ -7,88 +7,70 @@ use util::assert_err; mod util; +fn test(source: &str, name: &str) { + let mut map = Default::default(); + let module = assert_err(compile_module( + source, + name.to_owned(), + &mut map, + None, + true, + )); + + assert_err(perform_all_passes( + &mut mir::Context { + modules: vec![module], + base: Default::default(), + }, + &mut map, + )); +} + pub static ARRAY: &str = include_str!("../../reid_src/array.reid"); pub static FIBONACCI: &str = include_str!("../../reid_src/fibonacci.reid"); pub static HELLO_WORLD: &str = include_str!("../../reid_src/hello_world.reid"); pub static MUTABLE: &str = include_str!("../../reid_src/mutable.reid"); pub static STRINGS: &str = include_str!("../../reid_src/strings.reid"); +pub static ARRAYS: &str = include_str!("../../reid_src/array.reid"); +pub static STRUCTS: &str = include_str!("../../reid_src/struct.reid"); +pub static ARRAY_STRUCTS: &str = include_str!("../../reid_src/array_structs.reid"); #[test] fn array_compiles_well() { - let module = assert_err(compile_module( - ARRAY, - "array".to_owned(), - Default::default(), - None, - true, - )); - - assert_err(perform_all_passes(&mut mir::Context { - modules: vec![module], - base: Default::default(), - })); + test(ARRAY, "array"); } #[test] fn fibonacci_compiles_well() { - let module = assert_err(compile_module( - FIBONACCI, - "fibonacci".to_owned(), - Default::default(), - None, - true, - )); - - assert_err(perform_all_passes(&mut mir::Context { - modules: vec![module], - base: Default::default(), - })); + test(FIBONACCI, "fibonacci"); } #[test] fn hello_world_compiles_well() { - let module = assert_err(compile_module( - HELLO_WORLD, - "hello_world".to_owned(), - Default::default(), - None, - true, - )); - - assert_err(perform_all_passes(&mut mir::Context { - modules: vec![module], - base: Default::default(), - })); + test(HELLO_WORLD, "hello_world"); } #[test] fn mutable_compiles_well() { - let module = assert_err(compile_module( - MUTABLE, - "mutable".to_owned(), - Default::default(), - None, - true, - )); - - assert_err(perform_all_passes(&mut mir::Context { - modules: vec![module], - base: Default::default(), - })); + test(MUTABLE, "mutable"); } #[test] fn strings_compiles_well() { - let module = assert_err(compile_module( - STRINGS, - "strings".to_owned(), - Default::default(), - None, - true, - )); - - assert_err(perform_all_passes(&mut mir::Context { - modules: vec![module], - base: Default::default(), - })); + test(STRINGS, "strings"); +} + +#[test] +fn arrays_compiles_well() { + test(ARRAY, "array"); +} + +#[test] +fn struct_compiles_well() { + test(STRUCTS, "struct"); +} + +#[test] +fn array_structs_compiles_well() { + test(ARRAY_STRUCTS, "array_structs"); } diff --git a/reid/tests/stdlib.rs b/reid/tests/stdlib.rs index 1a2af28..97cf431 100644 --- a/reid/tests/stdlib.rs +++ b/reid/tests/stdlib.rs @@ -8,18 +8,22 @@ mod util; #[test] fn compiles() { - let _ = compile_std(Default::default()); + let _ = compile_std(&mut Default::default()); } #[test] fn passes_all_passes() { - let mut std = compile_std(Default::default()); + let mut map = Default::default(); + let mut std = compile_std(&mut map); // Needed to pass linker-pass std.is_main = true; - assert_err(perform_all_passes(&mut mir::Context { - modules: vec![std], - base: Default::default(), - })); + assert_err(perform_all_passes( + &mut mir::Context { + modules: vec![std], + base: Default::default(), + }, + &mut map, + )); }