diff --git a/compiler/erg_compiler/build_hir.rs b/compiler/erg_compiler/build_hir.rs index 6a731770..a74a95bc 100644 --- a/compiler/erg_compiler/build_hir.rs +++ b/compiler/erg_compiler/build_hir.rs @@ -1,6 +1,6 @@ use erg_common::config::ErgConfig; use erg_common::error::MultiErrorDisplay; -use erg_common::traits::{Runnable, Stream}; +use erg_common::traits::Runnable; use erg_common::Str; use erg_parser::ast::AST; @@ -8,7 +8,7 @@ use erg_parser::build_ast::ASTBuilder; use crate::context::Context; use crate::effectcheck::SideEffectChecker; -use crate::error::{CompileError, CompileErrors, TyCheckErrors}; +use crate::error::{CompileError, CompileErrors}; use crate::hir::HIR; use crate::lower::ASTLowerer; use crate::mod_cache::SharedModuleCache; @@ -48,7 +48,7 @@ impl Runnable for HIRBuilder { fn exec(&mut self) -> Result<(), Self::Errs> { let mut builder = ASTBuilder::new(self.cfg().copy()); let ast = builder.build(self.input().read())?; - let hir = self.check(ast, "exec")?; + let hir = self.check(ast, "exec").map_err(|(_, errs)| errs)?; println!("{hir}"); Ok(()) } @@ -56,7 +56,7 @@ impl Runnable for HIRBuilder { fn eval(&mut self, src: String) -> Result { let mut builder = ASTBuilder::new(self.cfg().copy()); let ast = builder.build(src)?; - let hir = self.check(ast, "eval")?; + let hir = self.check(ast, "eval").map_err(|(_, errs)| errs)?; Ok(hir.to_string()) } } @@ -69,41 +69,32 @@ impl HIRBuilder { py_mod_cache: SharedModuleCache, ) -> Self { Self { - lowerer: ASTLowerer::new_with_cache(cfg, mod_name, mod_cache, py_mod_cache), - ownership_checker: OwnershipChecker::new(), + lowerer: ASTLowerer::new_with_cache(cfg.copy(), mod_name, mod_cache, py_mod_cache), + ownership_checker: OwnershipChecker::new(cfg), } } - fn convert(&self, errs: TyCheckErrors) -> CompileErrors { - errs.into_iter() - .map(|e| CompileError::new(e.core, self.input().clone(), e.caused_by)) - .collect::>() - .into() - } - - pub fn check(&mut self, ast: AST, mode: &str) -> Result { - let (hir, warns) = self - .lowerer - .lower(ast, mode) - .map_err(|errs| self.convert(errs))?; + pub fn check(&mut self, ast: AST, mode: &str) -> Result, CompileErrors)> { + let (hir, warns) = self.lowerer.lower(ast, mode)?; if self.cfg().verbose >= 2 { - let warns = self.convert(warns); warns.fmt_all_stderr(); } - let effect_checker = SideEffectChecker::new(); + let effect_checker = SideEffectChecker::new(self.cfg().clone()); let hir = effect_checker .check(hir) - .map_err(|errs| self.convert(errs))?; + .map_err(|(hir, errs)| (Some(hir), errs))?; let hir = self .ownership_checker .check(hir) - .map_err(|errs| self.convert(errs))?; + .map_err(|(hir, errs)| (Some(hir), errs))?; Ok(hir) } - pub fn build(&mut self, src: String, mode: &str) -> Result { + pub fn build(&mut self, src: String, mode: &str) -> Result, CompileErrors)> { let mut ast_builder = ASTBuilder::new(self.cfg().copy()); - let ast = ast_builder.build(src)?; + let ast = ast_builder + .build(src) + .map_err(|errs| (None, CompileErrors::from(errs)))?; let hir = self.check(ast, mode)?; Ok(hir) } diff --git a/compiler/erg_compiler/codegen.rs b/compiler/erg_compiler/codegen.rs index 770c0ef3..f764be38 100644 --- a/compiler/erg_compiler/codegen.rs +++ b/compiler/erg_compiler/codegen.rs @@ -7,7 +7,7 @@ use std::process; use erg_common::astr::AtomicStr; use erg_common::cache::CacheSet; use erg_common::config::{ErgConfig, Input}; -use erg_common::error::{Location, MultiErrorDisplay}; +use erg_common::error::{ErrorDisplay, Location}; use erg_common::opcode::Opcode; use erg_common::traits::{Locational, Stream}; use erg_common::Str; @@ -30,7 +30,7 @@ use erg_type::{HasType, Type, TypeCode, TypePair}; use crate::compile::{AccessKind, Name, StoreLoadKind}; use crate::context::eval::eval_lit; -use crate::error::{CompileError, CompileErrors, CompileResult}; +use crate::error::CompileError; use crate::hir::{ Accessor, Args, Array, AttrDef, Attribute, BinOp, Block, Call, ClassDef, Def, DefBody, Expr, Identifier, Lambda, Literal, PosArg, Record, Signature, SubrSignature, Tuple, UnaryOp, @@ -345,7 +345,6 @@ pub struct CodeGenerator { prelude_loaded: bool, unit_size: usize, units: CodeGenStack, - pub(crate) errs: CompileErrors, } impl CodeGenerator { @@ -356,13 +355,11 @@ impl CodeGenerator { prelude_loaded: false, unit_size: 0, units: CodeGenStack::empty(), - errs: CompileErrors::empty(), } } pub fn clear(&mut self) { self.units.clear(); - self.errs.clear(); } #[inline] @@ -565,7 +562,7 @@ impl CodeGenerator { Name::local(self.cur_block_codeobj().names.len() - 1) } - fn emit_load_name_instr(&mut self, ident: Identifier) -> CompileResult<()> { + fn emit_load_name_instr(&mut self, ident: Identifier) { log!(info "entered {}", fn_name!()); let escaped = escape_name(ident); let name = self @@ -580,10 +577,9 @@ impl CodeGenerator { self.write_instr(instr); self.write_arg(name.idx as u8); self.stack_inc(); - Ok(()) } - fn emit_import_name_instr(&mut self, ident: Identifier, items_len: usize) -> CompileResult<()> { + fn emit_import_name_instr(&mut self, ident: Identifier, items_len: usize) { log!(info "entered {}", fn_name!()); let escaped = escape_name(ident); let name = self @@ -593,10 +589,9 @@ impl CodeGenerator { self.write_arg(name.idx as u8); self.stack_dec(); // (level + from_list) -> module object self.stack_inc_n(items_len - 1); - Ok(()) } - fn emit_import_from_instr(&mut self, ident: Identifier) -> CompileResult<()> { + fn emit_import_from_instr(&mut self, ident: Identifier) { log!(info "entered {}", fn_name!()); let escaped = escape_name(ident); let name = self @@ -605,7 +600,6 @@ impl CodeGenerator { self.write_instr(IMPORT_FROM); self.write_arg(name.idx as u8); // self.stack_inc(); (module object) -> attribute - Ok(()) } /// item: (name, renamed) @@ -621,13 +615,13 @@ impl CodeGenerator { .collect::>(); let items_len = item_names.len(); self.emit_load_const(item_names); - self.emit_import_name_instr(module, items_len).unwrap(); + self.emit_import_name_instr(module, items_len); for (item, renamed) in items.into_iter() { if let Some(renamed) = renamed { - self.emit_import_from_instr(item).unwrap(); + self.emit_import_from_instr(item); self.emit_store_instr(renamed, Name); } else { - self.emit_import_from_instr(item.clone()).unwrap(); + self.emit_import_from_instr(item.clone()); self.emit_store_instr(item, Name); } } @@ -638,7 +632,7 @@ impl CodeGenerator { class: &str, uniq_obj_name: Option<&str>, ident: Identifier, - ) -> CompileResult<()> { + ) { log!(info "entered {} ({class}{ident})", fn_name!()); let escaped = escape_attr(class, uniq_obj_name, ident); let name = self @@ -652,7 +646,6 @@ impl CodeGenerator { }; self.write_instr(instr); self.write_arg(name.idx as u8); - Ok(()) } fn emit_load_method_instr( @@ -660,7 +653,7 @@ impl CodeGenerator { class: &str, uniq_obj_name: Option<&str>, ident: Identifier, - ) -> CompileResult<()> { + ) { log!(info "entered {} ({class}{ident})", fn_name!()); let escaped = escape_attr(class, uniq_obj_name, ident); let name = self @@ -674,7 +667,6 @@ impl CodeGenerator { }; self.write_instr(instr); self.write_arg(name.idx as u8); - Ok(()) } fn emit_store_instr(&mut self, ident: Identifier, acc_kind: AccessKind) { @@ -746,7 +738,6 @@ impl CodeGenerator { /// Compileが継続不能になった際呼び出す /// 極力使わないこと fn crash(&mut self, description: &'static str) -> ! { - self.errs.fmt_all_stderr(); if cfg!(feature = "debug") { panic!("internal error: {description}"); } else { @@ -779,9 +770,7 @@ impl CodeGenerator { log!(info "entered {} ({acc})", fn_name!()); match acc { Accessor::Ident(ident) => { - self.emit_load_name_instr(ident).unwrap_or_else(|err| { - self.errs.push(err); - }); + self.emit_load_name_instr(ident); } Accessor::Attr(a) => { let class = a.obj.ref_t().name(); @@ -795,19 +784,14 @@ impl CodeGenerator { if Some(&self.cur_block_codeobj().name[..]) == a.obj.__name__() && &self.cur_block_codeobj().name[..] != "" { - self.emit_load_name_instr(a.ident).unwrap_or_else(|err| { - self.errs.push(err); - }); + self.emit_load_name_instr(a.ident); } else { self.emit_expr(*a.obj); self.emit_load_attr_instr( &class, uniq_obj_name.as_ref().map(|s| &s[..]), a.ident, - ) - .unwrap_or_else(|err| { - self.errs.push(err); - }); + ); } } Accessor::TupleAttr(t_attr) => { @@ -848,8 +832,7 @@ impl CodeGenerator { self.write_instr(Opcode::MAKE_FUNCTION); self.write_arg(0); self.emit_load_const(def.sig.ident().inspect().clone()); - self.emit_load_name_instr(Identifier::private(Str::ever("#ABCMeta"))) - .unwrap(); + self.emit_load_name_instr(Identifier::private(Str::ever("#ABCMeta"))); self.emit_load_const(vec![ValueObj::from("metaclass")]); let subclasses_len = 1; self.write_instr(Opcode::CALL_FUNCTION_KW); @@ -908,13 +891,14 @@ impl CodeGenerator { if self.cur_block().stack_len > 1 { let block_id = self.cur_block().id; let stack_len = self.cur_block().stack_len; - self.errs.push(CompileError::stack_bug( + CompileError::stack_bug( self.input().clone(), Location::Unknown, stack_len, block_id, fn_name_full!(), - )); + ) + .write_to_stderr(); self.crash("error in emit_trait_block: invalid stack size"); } // flagging @@ -944,7 +928,7 @@ impl CodeGenerator { log!(info "entered {} ({ident})", fn_name!()); let deco_is_some = deco.is_some(); if let Some(deco) = deco { - self.emit_load_name_instr(deco).unwrap(); + self.emit_load_name_instr(deco); } let code = { self.unit_size += 1; @@ -1096,12 +1080,13 @@ impl CodeGenerator { TokenKind::PreMinus => UNARY_NEGATIVE, TokenKind::Mutate => NOP, // ERG_MUTATE, _ => { - self.errs.push(CompileError::feature_error( + CompileError::feature_error( self.cfg.input.clone(), unary.op.loc(), "", AtomicStr::from(unary.op.content), - )); + ) + .write_to_stderr(); NOT_IMPLEMENTED } }; @@ -1116,8 +1101,7 @@ impl CodeGenerator { match &bin.op.kind { // l.. { - self.emit_load_name_instr(Identifier::public("range")) - .unwrap(); + self.emit_load_name_instr(Identifier::public("range")); } TokenKind::LeftOpen | TokenKind::Closed | TokenKind::Open => todo!(), _ => {} @@ -1144,12 +1128,13 @@ impl CodeGenerator { CALL_FUNCTION } // ERG_BINARY_RANGE, _ => { - self.errs.push(CompileError::feature_error( + CompileError::feature_error( self.cfg.input.clone(), bin.op.loc(), "", AtomicStr::from(bin.op.content), - )); + ) + .write_to_stderr(); NOT_IMPLEMENTED } }; @@ -1174,16 +1159,15 @@ impl CodeGenerator { } } - fn emit_discard_instr(&mut self, mut args: Args) -> CompileResult<()> { + fn emit_discard_instr(&mut self, mut args: Args) { log!(info "entered {}", fn_name!()); while let Some(arg) = args.try_remove(0) { self.emit_expr(arg); self.emit_pop_top(); } - Ok(()) } - fn emit_if_instr(&mut self, mut args: Args) -> CompileResult<()> { + fn emit_if_instr(&mut self, mut args: Args) { log!(info "entered {}", fn_name!()); let cond = args.remove(0); self.emit_expr(cond); @@ -1229,10 +1213,9 @@ impl CodeGenerator { self.stack_dec(); self.stack_dec(); } - Ok(()) } - fn emit_for_instr(&mut self, mut args: Args) -> CompileResult<()> { + fn emit_for_instr(&mut self, mut args: Args) { log!(info "entered {}", fn_name!()); let iterable = args.remove(0); self.emit_expr(iterable); @@ -1252,10 +1235,9 @@ impl CodeGenerator { let idx_end = self.cur_block().lasti; self.edit_code(idx_for_iter + 1, (idx_end - idx_for_iter - 2) / 2); self.emit_load_const(ValueObj::None); - Ok(()) } - fn emit_match_instr(&mut self, mut args: Args, _use_erg_specific: bool) -> CompileResult<()> { + fn emit_match_instr(&mut self, mut args: Args, _use_erg_specific: bool) { log!(info "entered {}", fn_name!()); let expr = args.remove(0); self.emit_expr(expr); @@ -1275,7 +1257,7 @@ impl CodeGenerator { todo!("default values in match expression are not supported yet") } let pat = lambda.params.non_defaults.remove(0).pat; - let pop_jump_points = self.emit_match_pattern(pat)?; + let pop_jump_points = self.emit_match_pattern(pat); self.emit_frameless_block(lambda.body, Vec::new()); for pop_jump_point in pop_jump_points.into_iter() { let idx = self.cur_block().lasti + 2; @@ -1289,10 +1271,9 @@ impl CodeGenerator { for absolute_jump_point in absolute_jump_points.into_iter() { self.edit_code(absolute_jump_point + 1, lasti / 2); } - Ok(()) } - fn emit_match_pattern(&mut self, pat: ParamPattern) -> CompileResult> { + fn emit_match_pattern(&mut self, pat: ParamPattern) -> Vec { log!(info "entered {}", fn_name!()); let mut pop_jump_points = vec![]; match pat { @@ -1333,7 +1314,7 @@ impl CodeGenerator { self.write_arg(len as u8); self.stack_inc_n(len - 1); for elem in arr.elems.non_defaults { - pop_jump_points.append(&mut self.emit_match_pattern(elem.pat)?); + pop_jump_points.append(&mut self.emit_match_pattern(elem.pat)); } if !arr.elems.defaults.is_empty() { todo!("default values in match are not supported yet") @@ -1343,7 +1324,7 @@ impl CodeGenerator { todo!() } } - Ok(pop_jump_points) + pop_jump_points } fn emit_call(&mut self, call: Call) { @@ -1353,7 +1334,7 @@ impl CodeGenerator { } else { match *call.obj { Expr::Accessor(Accessor::Ident(ident)) if ident.vis().is_private() => { - self.emit_call_local(ident, call.args).unwrap() + self.emit_call_local(ident, call.args) } other => { self.emit_expr(other); @@ -1363,7 +1344,7 @@ impl CodeGenerator { } } - fn emit_call_local(&mut self, local: Identifier, args: Args) -> CompileResult<()> { + fn emit_call_local(&mut self, local: Identifier, args: Args) { log!(info "entered {}", fn_name!()); match &local.inspect()[..] { "assert" => self.emit_assert_instr(args), @@ -1372,11 +1353,8 @@ impl CodeGenerator { "if" | "if!" => self.emit_if_instr(args), "match" | "match!" => self.emit_match_instr(args, true), _ => { - self.emit_load_name_instr(local).unwrap_or_else(|e| { - self.errs.push(e); - }); + self.emit_load_name_instr(local); self.emit_args(args, Name); - Ok(()) } } } @@ -1392,10 +1370,7 @@ impl CodeGenerator { return self.emit_call_fake_method(obj, method_name, args); } self.emit_expr(obj); - self.emit_load_method_instr(&class, uniq_obj_name.as_ref().map(|s| &s[..]), method_name) - .unwrap_or_else(|err| { - self.errs.push(err); - }); + self.emit_load_method_instr(&class, uniq_obj_name.as_ref().map(|s| &s[..]), method_name); self.emit_args(args, Method); } @@ -1471,13 +1446,13 @@ impl CodeGenerator { fn emit_call_fake_method(&mut self, obj: Expr, mut method_name: Identifier, mut args: Args) { log!(info "entered {}", fn_name!()); method_name.dot = None; - self.emit_load_name_instr(method_name).unwrap(); + self.emit_load_name_instr(method_name); args.insert_pos(0, PosArg::new(obj)); self.emit_args(args, Name); } // assert takes 1 or 2 arguments (0: cond, 1: message) - fn emit_assert_instr(&mut self, mut args: Args) -> CompileResult<()> { + fn emit_assert_instr(&mut self, mut args: Args) { log!(info "entered {}", fn_name!()); self.emit_expr(args.remove(0)); let pop_jump_point = self.cur_block().lasti; @@ -1495,7 +1470,6 @@ impl CodeGenerator { self.write_arg(1); let idx = self.cur_block().lasti; self.edit_code(pop_jump_point + 1, idx / 2); // jump to POP_TOP - Ok(()) } #[allow(clippy::identity_op)] @@ -1504,7 +1478,7 @@ impl CodeGenerator { let attrs_len = rec.attrs.len(); // making record type let ident = Identifier::private(Str::ever("#NamedTuple")); - self.emit_load_name_instr(ident).unwrap(); + self.emit_load_name_instr(ident); // record name, let it be anonymous self.emit_load_const("Record"); for field in rec.attrs.iter() { @@ -1525,7 +1499,7 @@ impl CodeGenerator { self.emit_store_instr(ident, Name); // making record instance let ident = Identifier::private(Str::ever("#rec")); - self.emit_load_name_instr(ident).unwrap(); + self.emit_load_name_instr(ident); for field in rec.attrs.into_iter() { self.emit_frameless_block(field.body.block, vec![]); } @@ -1557,13 +1531,14 @@ impl CodeGenerator { self.mut_cur_block().prev_lineno += ld; self.mut_cur_block().prev_lasti = self.cur_block().lasti; } else { - self.errs.push(CompileError::compiler_bug( + CompileError::compiler_bug( 0, self.cfg.input.clone(), expr.loc(), fn_name_full!(), line!(), - )); + ) + .write_to_stderr(); self.crash("codegen failed: invalid bytecode format"); } } @@ -1624,12 +1599,8 @@ impl CodeGenerator { } // Dict, other => { - self.errs.push(CompileError::feature_error( - self.cfg.input.clone(), - other.loc(), - "???", - "".into(), - )); + CompileError::feature_error(self.cfg.input.clone(), other.loc(), "???", "".into()) + .write_to_stderr(); self.crash("cannot compile this expression at this time"); } } @@ -1685,13 +1656,14 @@ impl CodeGenerator { if self.cur_block().stack_len > 1 { let block_id = self.cur_block().id; let stack_len = self.cur_block().stack_len; - self.errs.push(CompileError::stack_bug( + CompileError::stack_bug( self.input().clone(), Location::Unknown, stack_len, block_id, fn_name_full!(), - )); + ) + .write_to_stderr(); self.crash("error in emit_class_block: invalid stack size"); } // flagging @@ -1836,13 +1808,14 @@ impl CodeGenerator { } else if self.cur_block().stack_len > 1 { let block_id = self.cur_block().id; let stack_len = self.cur_block().stack_len; - self.errs.push(CompileError::stack_bug( + CompileError::stack_bug( self.input().clone(), Location::Unknown, stack_len, block_id, fn_name_full!(), - )); + ) + .write_to_stderr(); self.crash("error in emit_block: invalid stack size"); } self.write_instr(RETURN_VALUE); @@ -1928,8 +1901,7 @@ impl CodeGenerator { let mut print_point = 0; if self.input().is_repl() { print_point = self.cur_block().lasti; - self.emit_load_name_instr(Identifier::public("print")) - .unwrap(); + self.emit_load_name_instr(Identifier::public("print")); // Consistency will be taken later (when NOP replacing) // 後で(NOP書き換え時)整合性を取る self.stack_dec(); @@ -1958,13 +1930,14 @@ impl CodeGenerator { } else if self.cur_block().stack_len > 1 { let block_id = self.cur_block().id; let stack_len = self.cur_block().stack_len; - self.errs.push(CompileError::stack_bug( + CompileError::stack_bug( self.input().clone(), Location::Unknown, stack_len, block_id, fn_name_full!(), - )); + ) + .write_to_stderr(); self.crash("error in codegen: invalid stack size"); } self.write_instr(RETURN_VALUE); diff --git a/compiler/erg_compiler/compile.rs b/compiler/erg_compiler/compile.rs index a6f2a8dc..902d4a65 100644 --- a/compiler/erg_compiler/compile.rs +++ b/compiler/erg_compiler/compile.rs @@ -5,7 +5,7 @@ use std::path::Path; use erg_common::config::ErgConfig; use erg_common::log; -use erg_common::traits::{Runnable, Stream}; +use erg_common::traits::Runnable; use erg_type::codeobj::CodeObj; use crate::build_hir::HIRBuilder; @@ -155,18 +155,11 @@ impl Compiler { pub fn compile(&mut self, src: String, mode: &str) -> Result { log!(info "the compiling process has started."); - let hir = self.builder.build(src, mode)?; + let hir = self.builder.build(src, mode).map_err(|(_, errs)| errs)?; let hir = Linker::link(self.cfg.copy(), hir, self.mod_cache.clone()); let codeobj = self.code_generator.emit(hir); log!(info "code object:\n{}", codeobj.code_info()); - log!( - info "the compiling process has completed, found errors: {}", - self.code_generator.errs.len() - ); - if self.code_generator.errs.is_empty() { - Ok(codeobj) - } else { - Err(self.code_generator.errs.flush()) - } + log!(info "the compiling process has completed"); + Ok(codeobj) } } diff --git a/compiler/erg_compiler/context/compare.rs b/compiler/erg_compiler/context/compare.rs index 2d9fa91f..9956e0b3 100644 --- a/compiler/erg_compiler/context/compare.rs +++ b/compiler/erg_compiler/context/compare.rs @@ -549,29 +549,32 @@ impl Context { // REVIEW: maybe this should be `unreachable` let mut l_tv_ctx = TyVarContext::new(self.level, l.bounds.clone(), self); let mut r_tv_ctx = TyVarContext::new(self.level, r.bounds.clone(), self); - let l_callable = Self::instantiate_t( - l.unbound_callable.as_ref().clone(), - &mut l_tv_ctx, - Location::Unknown, - ) - .unwrap(); - let r_callable = Self::instantiate_t( - r.unbound_callable.as_ref().clone(), - &mut r_tv_ctx, - Location::Unknown, - ) - .unwrap(); + let l_callable = self + .instantiate_t( + l.unbound_callable.as_ref().clone(), + &mut l_tv_ctx, + Location::Unknown, + ) + .unwrap(); + let r_callable = self + .instantiate_t( + r.unbound_callable.as_ref().clone(), + &mut r_tv_ctx, + Location::Unknown, + ) + .unwrap(); self.structural_supertype_of(&l_callable, &r_callable) } (Quantified(q), r) => { // REVIEW: maybe this should be `unreachable` let mut tv_ctx = TyVarContext::new(self.level, q.bounds.clone(), self); - let q_callable = Self::instantiate_t( - q.unbound_callable.as_ref().clone(), - &mut tv_ctx, - Location::Unknown, - ) - .unwrap(); + let q_callable = self + .instantiate_t( + q.unbound_callable.as_ref().clone(), + &mut tv_ctx, + Location::Unknown, + ) + .unwrap(); self.structural_supertype_of(&q_callable, r) } (Or(l_or, r_or), rhs) => self.supertype_of(l_or, rhs) || self.supertype_of(r_or, rhs), diff --git a/compiler/erg_compiler/context/eval.rs b/compiler/erg_compiler/context/eval.rs index b5df3259..73818358 100644 --- a/compiler/erg_compiler/context/eval.rs +++ b/compiler/erg_compiler/context/eval.rs @@ -24,7 +24,7 @@ use erg_type::{ use crate::context::instantiate::TyVarContext; use crate::context::{ClassDefType, Context, RegistrationMode}; -use crate::error::{EvalError, EvalResult, TyCheckResult}; +use crate::error::{EvalError, EvalErrors, EvalResult, SingleEvalResult, TyCheckResult}; #[inline] pub fn type_from_token_kind(kind: TokenKind) -> Type { @@ -104,7 +104,7 @@ impl SubstContext { pub fn substitute(&self, quant_t: Type, ctx: &Context, loc: Location) -> TyCheckResult { let mut tv_ctx = TyVarContext::new(ctx.level, self.bounds.clone(), ctx); - let inst = Context::instantiate_t(quant_t, &mut tv_ctx, loc)?; + let inst = ctx.instantiate_t(quant_t, &mut tv_ctx, loc)?; for param in inst.typarams() { self.substitute_tp(¶m, ctx)?; } @@ -172,30 +172,32 @@ impl Context { if let Some(val) = self.rec_get_const_obj(ident.inspect()) { Ok(val.clone()) } else if ident.is_const() { - Err(EvalError::no_var_error( + Err(EvalErrors::from(EvalError::no_var_error( + self.cfg.input.clone(), line!() as usize, ident.loc(), self.caused_by(), ident.inspect(), self.get_similar_name(ident.inspect()), - )) + ))) } else { - Err(EvalError::not_const_expr( + Err(EvalErrors::from(EvalError::not_const_expr( + self.cfg.input.clone(), line!() as usize, acc.loc(), self.caused_by(), - )) + ))) } } Accessor::Attr(attr) => { let obj = self.eval_const_expr(&attr.obj, None)?; - self.eval_attr(obj, &attr.ident) + Ok(self.eval_attr(obj, &attr.ident)?) } _ => todo!(), } } - fn eval_attr(&self, obj: ValueObj, ident: &Identifier) -> EvalResult { + fn eval_attr(&self, obj: ValueObj, ident: &Identifier) -> SingleEvalResult { if let Some(val) = obj.try_get_attr(&Field::from(ident)) { return Ok(val); } @@ -214,6 +216,7 @@ impl Context { } } Err(EvalError::no_attr_error( + self.cfg.input.clone(), line!() as usize, ident.loc(), self.caused_by(), @@ -256,6 +259,7 @@ impl Context { Accessor::Ident(ident) => { let obj = self.rec_get_const_obj(ident.inspect()).ok_or_else(|| { EvalError::no_var_error( + self.cfg.input.clone(), line!() as usize, ident.loc(), self.caused_by(), @@ -266,6 +270,7 @@ impl Context { let subr = option_enum_unwrap!(obj, ValueObj::Subr) .ok_or_else(|| { EvalError::type_mismatch_error( + self.cfg.input.clone(), line!() as usize, ident.loc(), self.caused_by(), @@ -303,7 +308,7 @@ impl Context { .call(args, self.mod_name().clone(), __name__) .map_err(|mut e| { e.loc = loc; - EvalError::new(e, self.caused_by()) + EvalErrors::from(EvalError::new(e, self.cfg.input.clone(), self.caused_by())) }), } } @@ -315,11 +320,12 @@ impl Context { self.register_gen_const(def.sig.ident().unwrap(), obj)?; Ok(ValueObj::None) } else { - Err(EvalError::not_const_expr( + Err(EvalErrors::from(EvalError::not_const_expr( + self.cfg.input.clone(), line!() as usize, def.body.block.loc(), self.caused_by(), - )) + ))) } } @@ -351,6 +357,7 @@ impl Context { // HACK: should avoid cloning let mut record_ctx = Context::instant( Str::ever(""), + self.cfg.clone(), 2, self.mod_cache.clone(), self.py_mod_cache.clone(), @@ -423,6 +430,7 @@ impl Context { // HACK: should avoid cloning let mut lambda_ctx = Context::instant( Str::ever(""), + self.cfg.clone(), 0, self.mod_cache.clone(), self.py_mod_cache.clone(), @@ -511,30 +519,62 @@ impl Context { fn eval_bin(&self, op: OpKind, lhs: ValueObj, rhs: ValueObj) -> EvalResult { match op { - Add => lhs - .try_add(rhs) - .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), - Sub => lhs - .try_sub(rhs) - .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), - Mul => lhs - .try_mul(rhs) - .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), - Div => lhs - .try_div(rhs) - .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), - Gt => lhs - .try_gt(rhs) - .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), - Ge => lhs - .try_ge(rhs) - .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), - Eq => lhs - .try_eq(rhs) - .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), - Ne => lhs - .try_ne(rhs) - .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), + Add => lhs.try_add(rhs).ok_or_else(|| { + EvalErrors::from(EvalError::unreachable( + self.cfg.input.clone(), + fn_name!(), + line!(), + )) + }), + Sub => lhs.try_sub(rhs).ok_or_else(|| { + EvalErrors::from(EvalError::unreachable( + self.cfg.input.clone(), + fn_name!(), + line!(), + )) + }), + Mul => lhs.try_mul(rhs).ok_or_else(|| { + EvalErrors::from(EvalError::unreachable( + self.cfg.input.clone(), + fn_name!(), + line!(), + )) + }), + Div => lhs.try_div(rhs).ok_or_else(|| { + EvalErrors::from(EvalError::unreachable( + self.cfg.input.clone(), + fn_name!(), + line!(), + )) + }), + Gt => lhs.try_gt(rhs).ok_or_else(|| { + EvalErrors::from(EvalError::unreachable( + self.cfg.input.clone(), + fn_name!(), + line!(), + )) + }), + Ge => lhs.try_ge(rhs).ok_or_else(|| { + EvalErrors::from(EvalError::unreachable( + self.cfg.input.clone(), + fn_name!(), + line!(), + )) + }), + Eq => lhs.try_eq(rhs).ok_or_else(|| { + EvalErrors::from(EvalError::unreachable( + self.cfg.input.clone(), + fn_name!(), + line!(), + )) + }), + Ne => lhs.try_ne(rhs).ok_or_else(|| { + EvalErrors::from(EvalError::unreachable( + self.cfg.input.clone(), + fn_name!(), + line!(), + )) + }), other => todo!("{other}"), } } @@ -556,14 +596,22 @@ impl Context { if fv.is_linked() { self.eval_bin_tp(op, &*fv.crack(), r) } else { - Err(EvalError::unreachable(fn_name!(), line!())) + Err(EvalErrors::from(EvalError::unreachable( + self.cfg.input.clone(), + fn_name!(), + line!(), + ))) } } (l, TyParam::FreeVar(fv)) => { if fv.is_linked() { self.eval_bin_tp(op, l, &*fv.crack()) } else { - Err(EvalError::unreachable(fn_name!(), line!())) + Err(EvalErrors::from(EvalError::unreachable( + self.cfg.input.clone(), + fn_name!(), + line!(), + ))) } } (e @ TyParam::Erased(_), _) | (_, e @ TyParam::Erased(_)) => Ok(e.clone()), @@ -601,7 +649,13 @@ impl Context { TyParam::Mono(name) => self .rec_get_const_obj(name) .map(|v| TyParam::value(v.clone())) - .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), + .ok_or_else(|| { + EvalErrors::from(EvalError::unreachable( + self.cfg.input.clone(), + fn_name!(), + line!(), + )) + }), TyParam::BinOp { op, lhs, rhs } => self.eval_bin_tp(*op, lhs, rhs), TyParam::UnaryOp { op, val } => self.eval_unary_tp(*op, val), TyParam::App { name, args } => self.eval_app(name, args), @@ -673,6 +727,7 @@ impl Context { } for (_ty, ty_ctx) in self.get_nominal_super_type_ctxs(&sub).ok_or_else(|| { EvalError::no_var_error( + self.cfg.input.clone(), line!() as usize, t_loc, self.caused_by(), @@ -717,13 +772,14 @@ impl Context { } } let proj = mono_proj(*lhs, rhs); - Err(EvalError::no_candidate_error( + Err(EvalErrors::from(EvalError::no_candidate_error( + self.cfg.input.clone(), line!() as usize, &proj, t_loc, self.caused_by(), self.get_no_candidate_hint(&proj), - )) + ))) } Type::Ref(l) => Ok(ref_(self.eval_t_params(*l, level, t_loc)?)), Type::RefMut { before, after } => { @@ -797,7 +853,13 @@ impl Context { TyParam::Mono(name) => self .rec_get_const_obj(&name) .map(|v| enum_t(set![v.clone()])) - .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), + .ok_or_else(|| { + EvalErrors::from(EvalError::unreachable( + self.cfg.input.clone(), + fn_name!(), + line!(), + )) + }), TyParam::MonoQVar(name) => { panic!("Not instantiated type variable: {name}") } @@ -822,10 +884,17 @@ impl Context { } } TyParam::Type(_) => Ok(Type::Type), - TyParam::Mono(name) => self - .rec_get_const_obj(&name) - .map(|v| v.class()) - .ok_or_else(|| EvalError::unreachable(fn_name!(), line!())), + TyParam::Mono(name) => { + self.rec_get_const_obj(&name) + .map(|v| v.class()) + .ok_or_else(|| { + EvalErrors::from(EvalError::unreachable( + self.cfg.input.clone(), + fn_name!(), + line!(), + )) + }) + } other => todo!("{other}"), } } diff --git a/compiler/erg_compiler/context/initialize/mod.rs b/compiler/erg_compiler/context/initialize/mod.rs index 633ef7eb..f39fcf25 100644 --- a/compiler/erg_compiler/context/initialize/mod.rs +++ b/compiler/erg_compiler/context/initialize/mod.rs @@ -4,6 +4,7 @@ pub mod const_func; pub mod py_mods; +use erg_common::config::ErgConfig; use erg_common::error::Location; use erg_common::vis::Visibility; use erg_common::Str; @@ -127,7 +128,9 @@ impl Context { // FIXME: MethodDefsと再代入は違う fn register_poly_type(&mut self, t: Type, ctx: Self, muty: Mutability) { let mut tv_ctx = TyVarContext::new(self.level, ctx.type_params_bounds(), self); - let t = Self::instantiate_t(t, &mut tv_ctx, Location::Unknown).unwrap(); + let t = self + .instantiate_t(t, &mut tv_ctx, Location::Unknown) + .unwrap(); // FIXME: panic if let Some((_, root_ctx)) = self.poly_types.get_mut(&t.name()) { root_ctx.methods_list.push((ClassDefType::Simple(t), ctx)); @@ -180,10 +183,10 @@ impl Context { // 型境界はすべて各サブルーチンで定義する // push_subtype_boundなどはユーザー定義APIの型境界決定のために使用する fn init_builtin_traits(&mut self) { - let unpack = Self::mono_trait("Unpack", None, None, Self::TOP_LEVEL); - let inheritable_type = Self::mono_trait("InheritableType", None, None, Self::TOP_LEVEL); - let named = Self::mono_trait("Named", None, None, Self::TOP_LEVEL); - let mut mutable = Self::mono_trait("Mutable", None, None, Self::TOP_LEVEL); + let unpack = Self::builtin_mono_trait("Unpack", 2); + let inheritable_type = Self::builtin_mono_trait("InheritableType", 2); + let named = Self::builtin_mono_trait("Named", 2); + let mut mutable = Self::builtin_mono_trait("Mutable", 2); let proj = mono_proj(mono_q("Self"), "ImmutType"); let f_t = func(vec![param_t("old", proj.clone())], None, vec![], proj); let t = pr1_met(ref_mut(mono_q("Self"), None), f_t, NoneType); @@ -193,22 +196,16 @@ impl Context { ); mutable.register_builtin_decl("update!", t, Public); // REVIEW: Immutatable? - let mut immutizable = Self::mono_trait("Immutizable", None, None, Self::TOP_LEVEL); + let mut immutizable = Self::builtin_mono_trait("Immutizable", 2); immutizable.register_superclass(builtin_mono("Mutable"), &mutable); immutizable.register_builtin_decl("ImmutType", Type, Public); // REVIEW: Mutatable? - let mut mutizable = Self::mono_trait("Mutizable", None, None, Self::TOP_LEVEL); + let mut mutizable = Self::builtin_mono_trait("Mutizable", 2); mutizable.register_builtin_decl("MutType!", Type, Public); - let mut in_ = Self::poly_trait( - "In", - vec![PS::t("T", NonDefault)], - None, - None, - Self::TOP_LEVEL, - ); + let mut in_ = Self::builtin_poly_trait("In", vec![PS::t("T", NonDefault)], 2); let params = vec![PS::t("T", NonDefault)]; - let input = Self::poly_trait("Input", params.clone(), None, None, Self::TOP_LEVEL); - let output = Self::poly_trait("Output", params, None, None, Self::TOP_LEVEL); + let input = Self::builtin_poly_trait("Input", params.clone(), 2); + let output = Self::builtin_poly_trait("Output", params, 2); in_.register_superclass(poly("Input", vec![ty_tp(mono_q("T"))]), &input); let op_t = fn1_met(mono_q("T"), mono_q("I"), Bool); let op_t = quant( @@ -219,13 +216,7 @@ impl Context { // Erg does not have a trait equivalent to `PartialEq` in Rust // This means, Erg's `Float` cannot be compared with other `Float` // use `l - r < EPSILON` to check if two floats are almost equal - let mut eq = Self::poly_trait( - "Eq", - vec![PS::t("R", WithDefault)], - None, - None, - Self::TOP_LEVEL, - ); + let mut eq = Self::builtin_poly_trait("Eq", vec![PS::t("R", WithDefault)], 2); eq.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); // __eq__: |Self <: Eq()| Self.(Self) -> Bool let op_t = fn1_met(mono_q("Self"), mono_q("R"), Bool); @@ -237,13 +228,8 @@ impl Context { }, ); eq.register_builtin_decl("__eq__", op_t, Public); - let mut partial_ord = Self::poly_trait( - "PartialOrd", - vec![PS::t("R", WithDefault)], - None, - None, - Self::TOP_LEVEL, - ); + let mut partial_ord = + Self::builtin_poly_trait("PartialOrd", vec![PS::t("R", WithDefault)], 2); partial_ord.register_superclass(poly("Eq", vec![ty_tp(mono_q("R"))]), &eq); let op_t = fn1_met( mono_q("Self"), @@ -258,26 +244,20 @@ impl Context { }, ); partial_ord.register_builtin_decl("__partial_cmp__", op_t, Public); - let mut ord = Self::mono_trait("Ord", None, None, Self::TOP_LEVEL); + let mut ord = Self::builtin_mono_trait("Ord", 2); ord.register_superclass(poly("Eq", vec![ty_tp(builtin_mono("Self"))]), &eq); ord.register_superclass( poly("PartialOrd", vec![ty_tp(builtin_mono("Self"))]), &partial_ord, ); // FIXME: poly trait - let num = Self::mono_trait("Num", None, None, Self::TOP_LEVEL); + let num = Self::builtin_mono_trait("Num", 2); /* vec![ poly("Add", vec![]), poly("Sub", vec![]), poly("Mul", vec![]), ], */ - let mut seq = Self::poly_trait( - "Seq", - vec![PS::t("T", NonDefault)], - None, - None, - Self::TOP_LEVEL, - ); + let mut seq = Self::builtin_poly_trait("Seq", vec![PS::t("T", NonDefault)], 2); seq.register_superclass(poly("Output", vec![ty_tp(mono_q("T"))]), &output); let self_t = mono_q("Self"); let t = fn0_met(self_t.clone(), Nat); @@ -297,7 +277,7 @@ impl Context { let r_bound = static_instance("R", Type); let params = vec![PS::t("R", WithDefault)]; let ty_params = vec![ty_tp(mono_q("R"))]; - let mut add = Self::poly_trait("Add", params.clone(), None, None, Self::TOP_LEVEL); + let mut add = Self::builtin_poly_trait("Add", params.clone(), 2); // Rについて共変(__add__の型とは関係ない) add.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); let self_bound = subtypeof(mono_q("Self"), poly("Add", ty_params.clone())); @@ -309,7 +289,7 @@ impl Context { let op_t = quant(op_t, set! {r_bound.clone(), self_bound}); add.register_builtin_decl("__add__", op_t, Public); add.register_builtin_decl("Output", Type, Public); - let mut sub = Self::poly_trait("Sub", params.clone(), None, None, Self::TOP_LEVEL); + let mut sub = Self::builtin_poly_trait("Sub", params.clone(), 2); sub.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); let op_t = fn1_met( mono_q("Self"), @@ -320,7 +300,7 @@ impl Context { let op_t = quant(op_t, set! {r_bound.clone(), self_bound}); sub.register_builtin_decl("__sub__", op_t, Public); sub.register_builtin_decl("Output", Type, Public); - let mut mul = Self::poly_trait("Mul", params.clone(), None, None, Self::TOP_LEVEL); + let mut mul = Self::builtin_poly_trait("Mul", params.clone(), 2); mul.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); let op_t = fn1_met( mono_q("Self"), @@ -331,7 +311,7 @@ impl Context { let op_t = quant(op_t, set! {r_bound.clone(), self_bound}); mul.register_builtin_decl("__mul__", op_t, Public); mul.register_builtin_decl("Output", Type, Public); - let mut div = Self::poly_trait("Div", params, None, None, Self::TOP_LEVEL); + let mut div = Self::builtin_poly_trait("Div", params, 2); div.register_superclass(poly("Output", vec![ty_tp(mono_q("R"))]), &output); let op_t = fn1_met(mono_q("Self"), r, mono_proj(mono_q("Self"), "Output")); let self_bound = subtypeof(mono_q("Self"), poly("Div", ty_params.clone())); @@ -387,7 +367,7 @@ impl Context { } fn init_builtin_classes(&mut self) { - let mut obj = Self::mono_class("Obj", None, None, Self::TOP_LEVEL); + let mut obj = Self::builtin_mono_class("Obj", 2); let t = fn0_met(mono_q("Self"), mono_q("Self")); let t = quant(t, set! {subtypeof(mono_q("Self"), builtin_mono("Obj"))}); obj.register_builtin_impl("clone", t, Const, Public); @@ -402,13 +382,13 @@ impl Context { Immutable, Public, ); - let mut obj_in = Self::methods("In", None, None, Self::TOP_LEVEL); + let mut obj_in = Self::builtin_methods("In", 2); obj_in.register_builtin_impl("__in__", fn1_met(Obj, Type, Bool), Const, Public); obj.register_trait(Obj, poly("Eq", vec![ty_tp(Type)]), obj_in); - let mut obj_mutizable = Self::methods("Mutizable", None, None, Self::TOP_LEVEL); + let mut obj_mutizable = Self::builtin_methods("Mutizable", 1); obj_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Obj!"))); obj.register_trait(Obj, builtin_mono("Mutizable"), obj_mutizable); - let mut float = Self::mono_class("Float", None, None, Self::TOP_LEVEL); + let mut float = Self::builtin_mono_class("Float", 2); float.register_superclass(Obj, &obj); // TODO: support multi platform float.register_builtin_const("EPSILON", ValueObj::Float(2.220446049250313e-16)); @@ -416,7 +396,7 @@ impl Context { float.register_builtin_impl("Imag", Float, Const, Public); float.register_marker_trait(builtin_mono("Num")); float.register_marker_trait(builtin_mono("Ord")); - let mut float_partial_ord = Self::methods("PartialOrd", None, None, Self::TOP_LEVEL); + let mut float_partial_ord = Self::builtin_methods("PartialOrd", 2); float_partial_ord.register_builtin_impl( "__cmp__", fn1_met(Float, Float, builtin_mono("Ordering")), @@ -430,36 +410,36 @@ impl Context { ); // Float doesn't have an `Eq` implementation let op_t = fn1_met(Float, Float, Float); - let mut float_add = Self::methods("Add", None, None, Self::TOP_LEVEL); + let mut float_add = Self::builtin_methods("Add", 2); float_add.register_builtin_impl("__add__", op_t.clone(), Const, Public); float_add.register_builtin_const("Output", ValueObj::builtin_t(Float)); float.register_trait(Float, poly("Add", vec![ty_tp(Float)]), float_add); - let mut float_sub = Self::methods("Sub", None, None, Self::TOP_LEVEL); + let mut float_sub = Self::builtin_methods("Sub", 2); float_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public); float_sub.register_builtin_const("Output", ValueObj::builtin_t(Float)); float.register_trait(Float, poly("Sub", vec![ty_tp(Float)]), float_sub); - let mut float_mul = Self::methods("Mul", None, None, Self::TOP_LEVEL); + let mut float_mul = Self::builtin_methods("Mul", 2); float_mul.register_builtin_impl("__mul__", op_t.clone(), Const, Public); float_mul.register_builtin_const("Output", ValueObj::builtin_t(Float)); float_mul.register_builtin_const("PowOutput", ValueObj::builtin_t(Float)); float.register_trait(Float, poly("Mul", vec![ty_tp(Float)]), float_mul); - let mut float_div = Self::methods("Div", None, None, Self::TOP_LEVEL); + let mut float_div = Self::builtin_methods("Div", 2); float_div.register_builtin_impl("__div__", op_t, Const, Public); float_div.register_builtin_const("Output", ValueObj::builtin_t(Float)); float_div.register_builtin_const("ModOutput", ValueObj::builtin_t(Float)); float.register_trait(Float, poly("Div", vec![ty_tp(Float)]), float_div); - let mut float_mutizable = Self::methods("Mutizable", None, None, Self::TOP_LEVEL); + let mut float_mutizable = Self::builtin_methods("Mutizable", 2); float_mutizable .register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Float!"))); float.register_trait(Float, builtin_mono("Mutizable"), float_mutizable); // TODO: Int, Nat, Boolの継承元をRatioにする(今はFloat) - let mut ratio = Self::mono_class("Ratio", None, None, Self::TOP_LEVEL); + let mut ratio = Self::builtin_mono_class("Ratio", 2); ratio.register_superclass(Obj, &obj); ratio.register_builtin_impl("Real", Ratio, Const, Public); ratio.register_builtin_impl("Imag", Ratio, Const, Public); ratio.register_marker_trait(builtin_mono("Num")); ratio.register_marker_trait(builtin_mono("Ord")); - let mut ratio_partial_ord = Self::methods("PartialOrd", None, None, Self::TOP_LEVEL); + let mut ratio_partial_ord = Self::builtin_methods("PartialOrd", 2); ratio_partial_ord.register_builtin_impl( "__cmp__", fn1_met(Ratio, Ratio, builtin_mono("Ordering")), @@ -471,33 +451,33 @@ impl Context { poly("PartialOrd", vec![ty_tp(Ratio)]), ratio_partial_ord, ); - let mut ratio_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); + let mut ratio_eq = Self::builtin_methods("Eq", 2); ratio_eq.register_builtin_impl("__eq__", fn1_met(Ratio, Ratio, Bool), Const, Public); ratio.register_trait(Ratio, poly("Eq", vec![ty_tp(Ratio)]), ratio_eq); let op_t = fn1_met(Ratio, Ratio, Ratio); - let mut ratio_add = Self::methods("Add", None, None, Self::TOP_LEVEL); + let mut ratio_add = Self::builtin_methods("Add", 2); ratio_add.register_builtin_impl("__add__", op_t.clone(), Const, Public); ratio_add.register_builtin_const("Output", ValueObj::builtin_t(Ratio)); ratio.register_trait(Ratio, poly("Add", vec![ty_tp(Ratio)]), ratio_add); - let mut ratio_sub = Self::methods("Sub", None, None, Self::TOP_LEVEL); + let mut ratio_sub = Self::builtin_methods("Sub", 2); ratio_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public); ratio_sub.register_builtin_const("Output", ValueObj::builtin_t(Ratio)); ratio.register_trait(Ratio, poly("Sub", vec![ty_tp(Ratio)]), ratio_sub); - let mut ratio_mul = Self::methods("Mul", None, None, Self::TOP_LEVEL); + let mut ratio_mul = Self::builtin_methods("Mul", 2); ratio_mul.register_builtin_impl("__mul__", op_t.clone(), Const, Public); ratio_mul.register_builtin_const("Output", ValueObj::builtin_t(Ratio)); ratio_mul.register_builtin_const("PowOutput", ValueObj::builtin_t(Ratio)); ratio.register_trait(Ratio, poly("Mul", vec![ty_tp(Ratio)]), ratio_mul); - let mut ratio_div = Self::methods("Div", None, None, Self::TOP_LEVEL); + let mut ratio_div = Self::builtin_methods("Div", 2); ratio_div.register_builtin_impl("__div__", op_t, Const, Public); ratio_div.register_builtin_const("Output", ValueObj::builtin_t(Ratio)); ratio_div.register_builtin_const("ModOutput", ValueObj::builtin_t(Ratio)); ratio.register_trait(Ratio, poly("Div", vec![ty_tp(Ratio)]), ratio_div); - let mut ratio_mutizable = Self::methods("Mutizable", None, None, Self::TOP_LEVEL); + let mut ratio_mutizable = Self::builtin_methods("Mutizable", 2); ratio_mutizable .register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Ratio!"))); ratio.register_trait(Ratio, builtin_mono("Mutizable"), ratio_mutizable); - let mut int = Self::mono_class("Int", None, None, Self::TOP_LEVEL); + let mut int = Self::builtin_mono_class("Int", 2); int.register_superclass(Float, &float); // TODO: Float -> Ratio int.register_superclass(Obj, &obj); int.register_marker_trait(builtin_mono("Num")); @@ -506,7 +486,7 @@ impl Context { // class("Rational"), // class("Integral"), int.register_builtin_impl("abs", fn0_met(Int, Nat), Immutable, Public); - let mut int_partial_ord = Self::methods("PartialOrd", None, None, Self::TOP_LEVEL); + let mut int_partial_ord = Self::builtin_methods("PartialOrd", 2); int_partial_ord.register_builtin_impl( "__partial_cmp__", fn1_met(Int, Int, option(builtin_mono("Ordering"))), @@ -514,30 +494,30 @@ impl Context { Public, ); int.register_trait(Int, poly("PartialOrd", vec![ty_tp(Int)]), int_partial_ord); - let mut int_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); + let mut int_eq = Self::builtin_methods("Eq", 2); int_eq.register_builtin_impl("__eq__", fn1_met(Int, Int, Bool), Const, Public); int.register_trait(Int, poly("Eq", vec![ty_tp(Int)]), int_eq); // __div__ is not included in Int (cast to Ratio) let op_t = fn1_met(Int, Int, Int); - let mut int_add = Self::methods("Add", None, None, Self::TOP_LEVEL); + let mut int_add = Self::builtin_methods("Add", 2); int_add.register_builtin_impl("__add__", op_t.clone(), Const, Public); int_add.register_builtin_const("Output", ValueObj::builtin_t(Int)); int.register_trait(Int, poly("Add", vec![ty_tp(Int)]), int_add); - let mut int_sub = Self::methods("Sub", None, None, Self::TOP_LEVEL); + let mut int_sub = Self::builtin_methods("Sub", 2); int_sub.register_builtin_impl("__sub__", op_t.clone(), Const, Public); int_sub.register_builtin_const("Output", ValueObj::builtin_t(Int)); int.register_trait(Int, poly("Sub", vec![ty_tp(Int)]), int_sub); - let mut int_mul = Self::methods("Mul", None, None, Self::TOP_LEVEL); + let mut int_mul = Self::builtin_methods("Mul", 2); int_mul.register_builtin_impl("__mul__", op_t, Const, Public); int_mul.register_builtin_const("Output", ValueObj::builtin_t(Int)); int_mul.register_builtin_const("PowOutput", ValueObj::builtin_t(Nat)); int.register_trait(Int, poly("Mul", vec![ty_tp(Int)]), int_mul); - let mut int_mutizable = Self::methods("Mutizable", None, None, Self::TOP_LEVEL); + let mut int_mutizable = Self::builtin_methods("Mutizable", 2); int_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Int!"))); int.register_trait(Int, builtin_mono("Mutizable"), int_mutizable); int.register_builtin_impl("Real", Int, Const, Public); int.register_builtin_impl("Imag", Int, Const, Public); - let mut nat = Self::mono_class("Nat", None, None, Self::TOP_LEVEL); + let mut nat = Self::builtin_mono_class("Nat", 10); nat.register_superclass(Int, &int); nat.register_superclass(Float, &float); // TODO: Float -> Ratio nat.register_superclass(Obj, &obj); @@ -557,10 +537,10 @@ impl Context { ); nat.register_marker_trait(builtin_mono("Num")); nat.register_marker_trait(builtin_mono("Ord")); - let mut nat_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); + let mut nat_eq = Self::builtin_methods("Eq", 2); nat_eq.register_builtin_impl("__eq__", fn1_met(Nat, Nat, Bool), Const, Public); nat.register_trait(Nat, poly("Eq", vec![ty_tp(Nat)]), nat_eq); - let mut nat_partial_ord = Self::methods("PartialOrd", None, None, Self::TOP_LEVEL); + let mut nat_partial_ord = Self::builtin_methods("PartialOrd", 2); nat_partial_ord.register_builtin_impl( "__cmp__", fn1_met(Nat, Nat, builtin_mono("Ordering")), @@ -570,20 +550,20 @@ impl Context { nat.register_trait(Nat, poly("PartialOrd", vec![ty_tp(Nat)]), nat_partial_ord); // __sub__, __div__ is not included in Nat (cast to Int/ Ratio) let op_t = fn1_met(Nat, Nat, Nat); - let mut nat_add = Self::methods("Add", None, None, Self::TOP_LEVEL); + let mut nat_add = Self::builtin_methods("Add", 2); nat_add.register_builtin_impl("__add__", op_t.clone(), Const, Public); nat_add.register_builtin_const("Output", ValueObj::builtin_t(Nat)); nat.register_trait(Nat, poly("Add", vec![ty_tp(Nat)]), nat_add); - let mut nat_mul = Self::methods("Mul", None, None, Self::TOP_LEVEL); + let mut nat_mul = Self::builtin_methods("Mul", 2); nat_mul.register_builtin_impl("__mul__", op_t, Const, Public); nat_mul.register_builtin_const("Output", ValueObj::builtin_t(Nat)); nat.register_trait(Nat, poly("Mul", vec![ty_tp(Nat)]), nat_mul); - let mut nat_mutizable = Self::methods("Mutizable", None, None, Self::TOP_LEVEL); + let mut nat_mutizable = Self::builtin_methods("Mutizable", 2); nat_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Nat!"))); nat.register_trait(Nat, builtin_mono("Mutizable"), nat_mutizable); nat.register_builtin_impl("Real", Nat, Const, Public); nat.register_builtin_impl("Imag", Nat, Const, Public); - let mut bool_ = Self::mono_class("Bool", None, None, Self::TOP_LEVEL); + let mut bool_ = Self::builtin_mono_class("Bool", 10); bool_.register_superclass(Nat, &nat); bool_.register_superclass(Int, &int); bool_.register_superclass(Float, &float); // TODO: Float -> Ratio @@ -595,7 +575,7 @@ impl Context { bool_.register_builtin_impl("__or__", fn1_met(Bool, Bool, Bool), Const, Public); bool_.register_marker_trait(builtin_mono("Num")); bool_.register_marker_trait(builtin_mono("Ord")); - let mut bool_partial_ord = Self::methods("PartialOrd", None, None, Self::TOP_LEVEL); + let mut bool_partial_ord = Self::builtin_methods("PartialOrd", 2); bool_partial_ord.register_builtin_impl( "__cmp__", fn1_met(Bool, Bool, builtin_mono("Ordering")), @@ -607,18 +587,18 @@ impl Context { poly("PartialOrd", vec![ty_tp(Bool)]), bool_partial_ord, ); - let mut bool_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); + let mut bool_eq = Self::builtin_methods("Eq", 2); bool_eq.register_builtin_impl("__eq__", fn1_met(Bool, Bool, Bool), Const, Public); bool_.register_trait(Bool, poly("Eq", vec![ty_tp(Bool)]), bool_eq); - let mut bool_add = Self::methods("Add", None, None, Self::TOP_LEVEL); + let mut bool_add = Self::builtin_methods("Add", 2); bool_add.register_builtin_impl("__add__", fn1_met(Bool, Bool, Int), Const, Public); bool_add.register_builtin_const("Output", ValueObj::builtin_t(Nat)); bool_.register_trait(Bool, poly("Add", vec![ty_tp(Bool)]), bool_add); - let mut bool_mutizable = Self::methods("Mutizable", None, None, Self::TOP_LEVEL); + let mut bool_mutizable = Self::builtin_methods("Mutizable", 2); bool_mutizable .register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Bool!"))); bool_.register_trait(Bool, builtin_mono("Mutizable"), bool_mutizable); - let mut str_ = Self::mono_class("Str", None, None, Self::TOP_LEVEL); + let mut str_ = Self::builtin_mono_class("Str", 10); str_.register_superclass(Obj, &obj); str_.register_marker_trait(builtin_mono("Ord")); str_.register_builtin_impl( @@ -645,51 +625,46 @@ impl Context { Immutable, Public, ); - let mut str_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); + let mut str_eq = Self::builtin_methods("Eq", 2); str_eq.register_builtin_impl("__eq__", fn1_met(Str, Str, Bool), Const, Public); str_.register_trait(Str, poly("Eq", vec![ty_tp(Str)]), str_eq); - let mut str_seq = Self::methods("Seq", None, None, Self::TOP_LEVEL); + let mut str_seq = Self::builtin_methods("Seq", 2); str_seq.register_builtin_impl("len", fn0_met(Str, Nat), Const, Public); str_seq.register_builtin_impl("get", fn1_met(Str, Nat, Str), Const, Public); str_.register_trait(Str, poly("Seq", vec![ty_tp(Str)]), str_seq); - let mut str_add = Self::methods("Add", None, None, Self::TOP_LEVEL); + let mut str_add = Self::builtin_methods("Add", 2); str_add.register_builtin_impl("__add__", fn1_met(Str, Str, Str), Const, Public); str_add.register_builtin_const("Output", ValueObj::builtin_t(Str)); str_.register_trait(Str, poly("Add", vec![ty_tp(Str)]), str_add); - let mut str_mul = Self::methods("Mul", None, None, Self::TOP_LEVEL); + let mut str_mul = Self::builtin_methods("Mul", 2); str_mul.register_builtin_impl("__mul__", fn1_met(Str, Nat, Str), Const, Public); str_mul.register_builtin_const("Output", ValueObj::builtin_t(Str)); str_.register_trait(Str, poly("Mul", vec![ty_tp(Nat)]), str_mul); - let mut str_mutizable = Self::methods("Mutizable", None, None, Self::TOP_LEVEL); + let mut str_mutizable = Self::builtin_methods("Mutizable", 2); str_mutizable.register_builtin_const("MutType!", ValueObj::builtin_t(builtin_mono("Str!"))); str_.register_trait(Str, builtin_mono("Mutizable"), str_mutizable); - let mut type_ = Self::mono_class("Type", None, None, Self::TOP_LEVEL); + let mut type_ = Self::builtin_mono_class("Type", 2); type_.register_superclass(Obj, &obj); type_.register_builtin_impl("mro", array(Type, TyParam::erased(Nat)), Immutable, Public); type_.register_marker_trait(builtin_mono("Named")); - let mut type_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); + let mut type_eq = Self::builtin_methods("Eq", 2); type_eq.register_builtin_impl("__eq__", fn1_met(Type, Type, Bool), Const, Public); type_.register_trait(Type, poly("Eq", vec![ty_tp(Type)]), type_eq); - let mut class_type = Self::mono_class("ClassType", None, None, Self::TOP_LEVEL); + let mut class_type = Self::builtin_mono_class("ClassType", 2); class_type.register_superclass(Type, &type_); class_type.register_superclass(Obj, &obj); class_type.register_marker_trait(builtin_mono("Named")); - let mut class_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); + let mut class_eq = Self::builtin_methods("Eq", 2); class_eq.register_builtin_impl("__eq__", fn1_met(Class, Class, Bool), Const, Public); class_type.register_trait(Class, poly("Eq", vec![ty_tp(Class)]), class_eq); - let mut module = Self::mono_class("Module", None, None, Self::TOP_LEVEL); + let mut module = Self::builtin_mono_class("Module", 2); module.register_superclass(Obj, &obj); module.register_marker_trait(builtin_mono("Named")); - let mut module_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); + let mut module_eq = Self::builtin_methods("Eq", 2); module_eq.register_builtin_impl("__eq__", fn1_met(Module, Module, Bool), Const, Public); module.register_trait(Module, poly("Eq", vec![ty_tp(Module)]), module_eq); - let mut array_ = Self::poly_class( - "Array", - vec![PS::t_nd("T"), PS::named_nd("N", Nat)], - None, - None, - Self::TOP_LEVEL, - ); + let mut array_ = + Self::builtin_poly_class("Array", vec![PS::t_nd("T"), PS::named_nd("N", Nat)], 10); array_.register_superclass(Obj, &obj); array_.register_marker_trait(poly("Output", vec![ty_tp(mono_q("T"))])); let n = mono_q_tp("N"); @@ -713,7 +688,7 @@ impl Context { )); // [T; N].MutType! = [T; !N] (neither [T!; N] nor [T; N]!) array_.register_builtin_const("MutType!", mut_type); - let mut array_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); + let mut array_eq = Self::builtin_methods("Eq", 2); array_eq.register_builtin_impl( "__eq__", fn1_met(array_t.clone(), array_t.clone(), Bool), @@ -724,9 +699,9 @@ impl Context { array_.register_marker_trait(builtin_mono("Mutizable")); array_.register_marker_trait(poly("Seq", vec![ty_tp(mono_q("T"))])); // TODO: make Tuple6, Tuple7, ... etc. - let mut tuple_ = Self::mono_class("Tuple", None, None, Self::TOP_LEVEL); + let mut tuple_ = Self::builtin_mono_class("Tuple", 2); tuple_.register_superclass(Obj, &obj); - let mut tuple_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); + let mut tuple_eq = Self::builtin_methods("Eq", 2); tuple_eq.register_builtin_impl( "__eq__", fn1_met(builtin_mono("Tuple"), builtin_mono("Tuple"), Bool), @@ -738,11 +713,10 @@ impl Context { poly("Eq", vec![ty_tp(builtin_mono("Tuple"))]), tuple_eq, ); - let mut tuple1 = - Self::poly_class("Tuple1", vec![PS::t_nd("A")], None, None, Self::TOP_LEVEL); + let mut tuple1 = Self::builtin_poly_class("Tuple1", vec![PS::t_nd("A")], 2); tuple1.register_superclass(builtin_mono("Tuple"), &tuple_); tuple1.register_superclass(Obj, &obj); - let mut tuple1_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); + let mut tuple1_eq = Self::builtin_methods("Eq", 2); tuple1_eq.register_builtin_impl( "__eq__", fn1_met( @@ -758,16 +732,10 @@ impl Context { poly("Eq", vec![ty_tp(poly("Tuple1", vec![ty_tp(mono_q("A"))]))]), tuple1_eq, ); - let mut tuple2 = Self::poly_class( - "Tuple2", - vec![PS::t_nd("A"), PS::t_nd("B")], - None, - None, - Self::TOP_LEVEL, - ); + let mut tuple2 = Self::builtin_poly_class("Tuple2", vec![PS::t_nd("A"), PS::t_nd("B")], 2); tuple2.register_superclass(builtin_mono("Tuple"), &tuple_); tuple2.register_superclass(Obj, &obj); - let mut tuple2_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); + let mut tuple2_eq = Self::builtin_methods("Eq", 2); tuple2_eq.register_builtin_impl( "__eq__", fn1_met( @@ -789,16 +757,14 @@ impl Context { ), tuple2_eq, ); - let mut tuple3 = Self::poly_class( + let mut tuple3 = Self::builtin_poly_class( "Tuple3", vec![PS::t_nd("A"), PS::t_nd("B"), PS::t_nd("C")], - None, - None, - Self::TOP_LEVEL, + 2, ); tuple3.register_superclass(builtin_mono("Tuple"), &tuple_); tuple3.register_superclass(Obj, &obj); - let mut tuple3_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); + let mut tuple3_eq = Self::builtin_methods("Eq", 2); tuple3_eq.register_builtin_impl( "__eq__", fn1_met( @@ -829,16 +795,14 @@ impl Context { ), tuple3_eq, ); - let mut tuple4 = Self::poly_class( + let mut tuple4 = Self::builtin_poly_class( "Tuple4", vec![PS::t_nd("A"), PS::t_nd("B"), PS::t_nd("C"), PS::t_nd("D")], - None, - None, - Self::TOP_LEVEL, + 2, ); tuple4.register_superclass(builtin_mono("Tuple"), &tuple_); tuple4.register_superclass(Obj, &obj); - let mut tuple4_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); + let mut tuple4_eq = Self::builtin_methods("Eq", 2); tuple4_eq.register_builtin_impl( "__eq__", fn1_met( @@ -889,7 +853,7 @@ impl Context { ), tuple4_eq, ); - let mut tuple5 = Self::poly_class( + let mut tuple5 = Self::builtin_poly_class( "Tuple5", vec![ PS::t_nd("A"), @@ -898,13 +862,11 @@ impl Context { PS::t_nd("D"), PS::t_nd("E"), ], - None, - None, - Self::TOP_LEVEL, + 2, ); tuple5.register_superclass(builtin_mono("Tuple"), &tuple_); tuple5.register_superclass(Obj, &obj); - let mut tuple5_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); + let mut tuple5_eq = Self::builtin_methods("Eq", 2); tuple5_eq.register_builtin_impl( "__eq__", fn1_met( @@ -959,7 +921,7 @@ impl Context { ), tuple5_eq, ); - let mut tuple6 = Self::poly_class( + let mut tuple6 = Self::builtin_poly_class( "Tuple6", vec![ PS::t_nd("A"), @@ -969,13 +931,11 @@ impl Context { PS::t_nd("E"), PS::t_nd("F"), ], - None, - None, - Self::TOP_LEVEL, + 2, ); tuple6.register_superclass(builtin_mono("Tuple"), &tuple_); tuple6.register_superclass(Obj, &obj); - let mut tuple6_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); + let mut tuple6_eq = Self::builtin_methods("Eq", 2); tuple6_eq.register_builtin_impl( "__eq__", fn1_met( @@ -1034,7 +994,7 @@ impl Context { ), tuple6_eq, ); - let mut tuple7 = Self::poly_class( + let mut tuple7 = Self::builtin_poly_class( "Tuple7", vec![ PS::t_nd("A"), @@ -1045,13 +1005,11 @@ impl Context { PS::t_nd("F"), PS::t_nd("G"), ], - None, - None, - Self::TOP_LEVEL, + 2, ); tuple7.register_superclass(builtin_mono("Tuple"), &tuple_); tuple7.register_superclass(Obj, &obj); - let mut tuple7_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); + let mut tuple7_eq = Self::builtin_methods("Eq", 2); tuple7_eq.register_builtin_impl( "__eq__", fn1_met( @@ -1114,7 +1072,7 @@ impl Context { ), tuple7_eq, ); - let mut tuple8 = Self::poly_class( + let mut tuple8 = Self::builtin_poly_class( "Tuple8", vec![ PS::t_nd("A"), @@ -1126,13 +1084,11 @@ impl Context { PS::t_nd("G"), PS::t_nd("H"), ], - None, - None, - Self::TOP_LEVEL, + 2, ); tuple8.register_superclass(builtin_mono("Tuple"), &tuple_); tuple8.register_superclass(Obj, &obj); - let mut tuple8_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); + let mut tuple8_eq = Self::builtin_methods("Eq", 2); tuple8_eq.register_builtin_impl( "__eq__", fn1_met( @@ -1199,16 +1155,16 @@ impl Context { ), tuple8_eq, ); - let mut record = Self::mono_class("Record", None, None, Self::TOP_LEVEL); + let mut record = Self::builtin_mono_class("Record", 2); record.register_superclass(Obj, &obj); - let mut record_type = Self::mono_class("RecordType", None, None, Self::TOP_LEVEL); + let mut record_type = Self::builtin_mono_class("RecordType", 2); record_type.register_superclass(builtin_mono("Record"), &record); record_type.register_superclass(builtin_mono("Type"), &type_); record_type.register_superclass(Obj, &obj); - let mut float_mut = Self::mono_class("Float!", None, None, Self::TOP_LEVEL); + let mut float_mut = Self::builtin_mono_class("Float!", 2); float_mut.register_superclass(Float, &float); float_mut.register_superclass(Obj, &obj); - let mut float_mut_mutable = Self::methods("Mutable", None, None, Self::TOP_LEVEL); + let mut float_mut_mutable = Self::builtin_methods("Mutable", 2); float_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Float)); let f_t = param_t("f", func(vec![param_t("old", Float)], None, vec![], Float)); let t = pr_met( @@ -1224,10 +1180,10 @@ impl Context { builtin_mono("Mutable"), float_mut_mutable, ); - let mut ratio_mut = Self::mono_class("Ratio!", None, None, Self::TOP_LEVEL); + let mut ratio_mut = Self::builtin_mono_class("Ratio!", 2); ratio_mut.register_superclass(Ratio, &ratio); ratio_mut.register_superclass(Obj, &obj); - let mut ratio_mut_mutable = Self::methods("Mutable", None, None, Self::TOP_LEVEL); + let mut ratio_mut_mutable = Self::builtin_methods("Mutable", 2); ratio_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Ratio)); let f_t = param_t( "f", @@ -1251,11 +1207,11 @@ impl Context { builtin_mono("Mutable"), ratio_mut_mutable, ); - let mut int_mut = Self::mono_class("Int!", None, None, Self::TOP_LEVEL); + let mut int_mut = Self::builtin_mono_class("Int!", 2); int_mut.register_superclass(Int, &int); int_mut.register_superclass(builtin_mono("Float!"), &float_mut); int_mut.register_superclass(Obj, &obj); - let mut int_mut_mutable = Self::methods("Mutable", None, None, Self::TOP_LEVEL); + let mut int_mut_mutable = Self::builtin_methods("Mutable", 2); int_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Int)); let f_t = param_t("f", func(vec![param_t("old", Int)], None, vec![], Int)); let t = pr_met( @@ -1271,12 +1227,12 @@ impl Context { builtin_mono("Mutable"), int_mut_mutable, ); - let mut nat_mut = Self::mono_class("Nat!", None, None, Self::TOP_LEVEL); + let mut nat_mut = Self::builtin_mono_class("Nat!", 2); nat_mut.register_superclass(Nat, &nat); nat_mut.register_superclass(builtin_mono("Int!"), &int_mut); nat_mut.register_superclass(builtin_mono("Float!"), &float_mut); nat_mut.register_superclass(Obj, &obj); - let mut nat_mut_mutable = Self::methods("Mutable", None, None, Self::TOP_LEVEL); + let mut nat_mut_mutable = Self::builtin_methods("Mutable", 2); nat_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Nat)); let f_t = param_t("f", func(vec![param_t("old", Nat)], None, vec![], Nat)); let t = pr_met( @@ -1292,13 +1248,13 @@ impl Context { builtin_mono("Mutable"), nat_mut_mutable, ); - let mut bool_mut = Self::mono_class("Bool!", None, None, Self::TOP_LEVEL); + let mut bool_mut = Self::builtin_mono_class("Bool!", 2); bool_mut.register_superclass(Bool, &bool_); bool_mut.register_superclass(builtin_mono("Nat!"), &nat_mut); bool_mut.register_superclass(builtin_mono("Int!"), &int_mut); bool_mut.register_superclass(builtin_mono("Float!"), &float_mut); bool_mut.register_superclass(Obj, &obj); - let mut bool_mut_mutable = Self::methods("Mutable", None, None, Self::TOP_LEVEL); + let mut bool_mut_mutable = Self::builtin_methods("Mutable", 2); bool_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Bool)); let f_t = param_t("f", func(vec![param_t("old", Bool)], None, vec![], Bool)); let t = pr_met( @@ -1314,10 +1270,10 @@ impl Context { builtin_mono("Mutable"), bool_mut_mutable, ); - let mut str_mut = Self::mono_class("Str!", None, None, Self::TOP_LEVEL); + let mut str_mut = Self::builtin_mono_class("Str!", 2); str_mut.register_superclass(Str, &str_); str_mut.register_superclass(Obj, &obj); - let mut str_mut_mutable = Self::methods("Mutable", None, None, Self::TOP_LEVEL); + let mut str_mut_mutable = Self::builtin_methods("Mutable", 2); str_mut_mutable.register_builtin_const("ImmutType", ValueObj::builtin_t(Str)); let f_t = param_t("f", func(vec![param_t("old", Str)], None, vec![], Str)); let t = pr_met( @@ -1335,12 +1291,10 @@ impl Context { ); let array_t = poly("Array", vec![ty_tp(mono_q("T")), mono_q_tp("N")]); let array_mut_t = poly("Array!", vec![ty_tp(mono_q("T")), mono_q_tp("N")]); - let mut array_mut_ = Self::poly_class( + let mut array_mut_ = Self::builtin_poly_class( "Array!", vec![PS::t_nd("T"), PS::named_nd("N", builtin_mono("Nat!"))], - None, - None, - Self::TOP_LEVEL, + 2, ); array_mut_.register_superclass(array_t.clone(), &array_); array_mut_.register_superclass(Obj, &obj); @@ -1393,7 +1347,7 @@ impl Context { vec![], NoneType, ); - let mut array_mut_mutable = Self::methods("Mutable", None, None, Self::TOP_LEVEL); + let mut array_mut_mutable = Self::builtin_methods("Mutable", 2); array_mut_mutable.register_builtin_impl("update!", t, Immutable, Public); array_mut_.register_trait( array_mut_t.clone(), @@ -1401,10 +1355,10 @@ impl Context { array_mut_mutable, ); let range_t = poly("Range", vec![TyParam::t(mono_q("T"))]); - let mut range = Self::poly_class("Range", vec![PS::t_nd("T")], None, None, Self::TOP_LEVEL); + let mut range = Self::builtin_poly_class("Range", vec![PS::t_nd("T")], 2); range.register_superclass(Obj, &obj); range.register_marker_trait(poly("Output", vec![ty_tp(mono_q("T"))])); - let mut range_eq = Self::methods("Eq", None, None, Self::TOP_LEVEL); + let mut range_eq = Self::builtin_methods("Eq", 2); range_eq.register_builtin_impl( "__eq__", fn1_met(range_t.clone(), range_t.clone(), Bool), @@ -1416,16 +1370,16 @@ impl Context { poly("Eq", vec![ty_tp(range_t.clone())]), range_eq, ); - let mut proc = Self::mono_class("Proc", None, None, Self::TOP_LEVEL); + let mut proc = Self::builtin_mono_class("Proc", 2); proc.register_superclass(Obj, &obj); // TODO: lambda proc.register_marker_trait(builtin_mono("Named")); - let mut func = Self::mono_class("Func", None, None, Self::TOP_LEVEL); + let mut func = Self::builtin_mono_class("Func", 2); func.register_superclass(builtin_mono("Proc"), &proc); func.register_superclass(Obj, &obj); // TODO: lambda func.register_marker_trait(builtin_mono("Named")); - let mut qfunc = Self::mono_class("QuantifiedFunc", None, None, Self::TOP_LEVEL); + let mut qfunc = Self::builtin_mono_class("QuantifiedFunc", 2); qfunc.register_superclass(builtin_mono("Func"), &func); qfunc.register_superclass(Obj, &obj); self.register_builtin_type(Obj, obj, Const); @@ -1804,20 +1758,13 @@ impl Context { PS::named_nd("P", Int), ]; // Interval is a bounding patch connecting M..N and (Add(O..P, M+O..N..P), Sub(O..P, M-P..N-O)) - let mut interval = Self::poly_patch( - "Interval", - params, - // super: vec![Type::from(&m..=&n)], - None, - None, - Self::TOP_LEVEL, - ); + let mut interval = Self::builtin_poly_patch("Interval", Type::from(&m..=&n), params, 2); let op_t = fn1_met( Type::from(&m..=&n), Type::from(&o..=&p), Type::from(m.clone() + o.clone()..=n.clone() + p.clone()), ); - let mut interval_add = Self::methods("Add", None, None, Self::TOP_LEVEL); + let mut interval_add = Self::builtin_methods("Add", 2); interval_add.register_builtin_impl("__add__", op_t, Const, Public); interval_add.register_builtin_const( "Output", @@ -1828,7 +1775,7 @@ impl Context { poly("Add", vec![TyParam::from(&o..=&p)]), interval_add, ); - let mut interval_sub = Self::methods("Sub", None, None, Self::TOP_LEVEL); + let mut interval_sub = Self::builtin_methods("Sub", 2); let op_t = fn1_met( Type::from(&m..=&n), Type::from(&o..=&p), @@ -1853,7 +1800,7 @@ impl Context { pub(crate) fn init_builtins(mod_cache: &SharedModuleCache) { // TODO: capacityを正確に把握する - let mut ctx = Context::module("".into(), None, None, 40); + let mut ctx = Context::module("".into(), ErgConfig::default(), None, None, 40); ctx.init_builtin_funcs(); ctx.init_builtin_const_funcs(); ctx.init_builtin_procs(); @@ -1866,11 +1813,13 @@ impl Context { pub fn new_module>( name: S, + cfg: ErgConfig, mod_cache: SharedModuleCache, py_mod_cache: SharedModuleCache, ) -> Self { Context::new( name.into(), + cfg, ContextKind::Module, vec![], None, diff --git a/compiler/erg_compiler/context/initialize/py_mods/importlib.rs b/compiler/erg_compiler/context/initialize/py_mods/importlib.rs index d84200ce..c69636a3 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/importlib.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/importlib.rs @@ -11,7 +11,7 @@ use Visibility::*; impl Context { pub(crate) fn init_py_importlib_mod() -> Self { - let mut importlib = Context::module("importlib".into(), None, None, 15); + let mut importlib = Context::builtin_module("importlib", 15); importlib.register_builtin_impl("reload!", proc1(Module, NoneType), Immutable, Public); importlib } diff --git a/compiler/erg_compiler/context/initialize/py_mods/io.rs b/compiler/erg_compiler/context/initialize/py_mods/io.rs index 6823676c..5361d03f 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/io.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/io.rs @@ -1,5 +1,4 @@ use erg_common::vis::Visibility; -use erg_common::Str; use erg_type::constructors::{builtin_mono, pr0_met, ref_}; use erg_type::Type; @@ -12,8 +11,8 @@ use Visibility::*; impl Context { pub(crate) fn init_py_io_mod() -> Self { - let mut io = Context::module("io".into(), None, None, 15); - let mut string_io = Context::mono_class(Str::ever("StringIO!"), None, None, 0); + let mut io = Context::builtin_module("io", 15); + let mut string_io = Context::builtin_mono_class("StringIO!", 0); // FIXME: include Obj (pass main_ctx as a param) // string_io.register_superclass(Obj, obj); string_io.register_builtin_impl( diff --git a/compiler/erg_compiler/context/initialize/py_mods/math.rs b/compiler/erg_compiler/context/initialize/py_mods/math.rs index c285c4b8..32bcb102 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/math.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/math.rs @@ -11,7 +11,7 @@ use Visibility::*; impl Context { pub(crate) fn init_py_math_mod() -> Self { - let mut math = Context::module("math".into(), None, None, 10); + let mut math = Context::builtin_module("math", 10); math.register_builtin_impl("pi", Float, Immutable, Public); math.register_builtin_impl("tau", Float, Immutable, Public); math.register_builtin_impl("e", Float, Immutable, Public); diff --git a/compiler/erg_compiler/context/initialize/py_mods/random.rs b/compiler/erg_compiler/context/initialize/py_mods/random.rs index 47aee9d6..d7419f31 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/random.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/random.rs @@ -14,7 +14,7 @@ use Visibility::*; impl Context { pub(crate) fn init_py_random_mod() -> Self { - let mut random = Context::module("random".into(), None, None, 10); + let mut random = Context::builtin_module("random", 10); random.register_builtin_impl( "seed!", proc( diff --git a/compiler/erg_compiler/context/initialize/py_mods/socket.rs b/compiler/erg_compiler/context/initialize/py_mods/socket.rs index f483aece..175cf165 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/socket.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/socket.rs @@ -1,5 +1,4 @@ use erg_common::vis::Visibility; -use erg_common::Str; use erg_type::constructors::{builtin_mono, func, option, param_t}; use erg_type::Type; @@ -12,8 +11,8 @@ use Visibility::*; impl Context { pub(crate) fn init_py_socket_mod() -> Self { - let mut socket = Context::module("socket".into(), None, None, 15); - let mut sock = Context::mono_class(Str::ever("Socket!"), None, None, 0); + let mut socket = Context::builtin_module("socket", 15); + let mut sock = Context::builtin_mono_class("Socket!", 0); // FIXME: include Obj (pass main_ctx as a param) // sock.register_superclass(Obj, obj); sock.register_builtin_impl( diff --git a/compiler/erg_compiler/context/initialize/py_mods/sys.rs b/compiler/erg_compiler/context/initialize/py_mods/sys.rs index fbb81c12..3d605e4b 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/sys.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/sys.rs @@ -12,7 +12,7 @@ use Visibility::*; impl Context { pub(crate) fn init_py_sys_mod() -> Self { - let mut sys = Context::module("sys".into(), None, None, 15); + let mut sys = Context::builtin_module("sys", 15); sys.register_builtin_impl("argv", array(Str, TyParam::erased(Nat)), Immutable, Public); sys.register_builtin_impl("byteorder", Str, Immutable, Public); sys.register_builtin_impl( diff --git a/compiler/erg_compiler/context/initialize/py_mods/time.rs b/compiler/erg_compiler/context/initialize/py_mods/time.rs index fc542b79..3492b67b 100644 --- a/compiler/erg_compiler/context/initialize/py_mods/time.rs +++ b/compiler/erg_compiler/context/initialize/py_mods/time.rs @@ -11,7 +11,7 @@ use Visibility::*; impl Context { pub(crate) fn init_py_time_mod() -> Self { - let mut time = Context::module("time".into(), None, None, 15); + let mut time = Context::builtin_module("time", 15); time.register_builtin_impl("sleep!", proc1(Float, NoneType), Immutable, Public); time.register_builtin_impl("time!", proc0(Float), Immutable, Public); time diff --git a/compiler/erg_compiler/context/inquire.rs b/compiler/erg_compiler/context/inquire.rs index b34f8c3e..5352fc9f 100644 --- a/compiler/erg_compiler/context/inquire.rs +++ b/compiler/erg_compiler/context/inquire.rs @@ -4,7 +4,7 @@ use std::option::Option; // conflicting to Type::Option use erg_common::error::{ErrorCore, ErrorKind, Location}; use erg_common::levenshtein::get_similar_name; use erg_common::set::Set; -use erg_common::traits::Locational; +use erg_common::traits::{Locational, Stream}; use erg_common::vis::{Field, Visibility}; use erg_common::Str; use erg_common::{enum_unwrap, fmt_option, fmt_slice, log, set}; @@ -20,8 +20,10 @@ use erg_type::{HasType, ParamTy, SubrKind, SubrType, TyBound, Type}; use crate::context::instantiate::ConstTemplate; use crate::context::{Context, RegistrationMode, TraitInstance, Variance}; -use crate::error::readable_name; -use crate::error::{binop_to_dname, unaryop_to_dname, TyCheckError, TyCheckResult}; +use crate::error::{ + binop_to_dname, readable_name, unaryop_to_dname, SingleTyCheckResult, TyCheckError, + TyCheckErrors, TyCheckResult, +}; use crate::hir; use crate::varinfo::VarInfo; use RegistrationMode::*; @@ -40,7 +42,8 @@ impl Context { .sub_unify(body_t, &spec_t, None, Some(ident.loc()), None) .is_err() { - return Err(TyCheckError::type_mismatch_error( + return Err(TyCheckErrors::from(TyCheckError::type_mismatch_error( + self.cfg.input.clone(), line!() as usize, ident.loc(), self.caused_by(), @@ -49,7 +52,7 @@ impl Context { body_t, self.get_candidates(body_t), self.get_type_mismatch_hint(&spec_t, body_t), - )); + ))); } Ok(()) } @@ -83,13 +86,14 @@ impl Context { self.locals.get_key_value(name) } - fn get_singular_ctx(&self, obj: &hir::Expr, namespace: &Str) -> TyCheckResult<&Context> { + fn get_singular_ctx(&self, obj: &hir::Expr, namespace: &Str) -> SingleTyCheckResult<&Context> { match obj { hir::Expr::Accessor(hir::Accessor::Ident(ident)) => self .get_mod(ident.inspect()) .or_else(|| self.rec_get_type(ident.inspect()).map(|(_, ctx)| ctx)) .ok_or_else(|| { TyCheckError::no_var_error( + self.cfg.input.clone(), line!() as usize, obj.loc(), namespace.into(), @@ -119,7 +123,8 @@ impl Context { let t = pos_arg.expr.ref_t(); // Allow only anonymous functions to be passed as match arguments (for aesthetic reasons) if !matches!(&pos_arg.expr, hir::Expr::Lambda(_)) { - return Err(TyCheckError::type_mismatch_error( + return Err(TyCheckErrors::from(TyCheckError::type_mismatch_error( + self.cfg.input.clone(), line!() as usize, pos_arg.loc(), self.caused_by(), @@ -128,7 +133,7 @@ impl Context { t, self.get_candidates(t), self.get_type_mismatch_hint(&builtin_mono("LambdaFunc"), t), - )); + ))); } } let match_target_expr_t = pos_args[0].expr.ref_t(); @@ -141,7 +146,8 @@ impl Context { } // TODO: If the first argument of the match is a tuple? if lambda.params.len() != 1 { - return Err(TyCheckError::argument_error( + return Err(TyCheckErrors::from(TyCheckError::argument_error( + self.cfg.input.clone(), line!() as usize, pos_args[i + 1].loc(), self.caused_by(), @@ -152,7 +158,7 @@ impl Context { .unwrap() .typarams_len() .unwrap_or(0), - )); + ))); } let rhs = self.instantiate_param_sig_t( &lambda.params.non_defaults[0], @@ -168,12 +174,13 @@ impl Context { .sub_unify(match_target_expr_t, &union_pat_t, None, None, None) .is_err() { - return Err(TyCheckError::match_error( + return Err(TyCheckErrors::from(TyCheckError::match_error( + self.cfg.input.clone(), line!() as usize, pos_args[0].loc(), self.caused_by(), match_target_expr_t, - )); + ))); } let branch_ts = pos_args .iter() @@ -201,7 +208,11 @@ impl Context { None } - pub(crate) fn rec_get_var_t(&self, ident: &Identifier, namespace: &Str) -> TyCheckResult { + pub(crate) fn rec_get_var_t( + &self, + ident: &Identifier, + namespace: &Str, + ) -> SingleTyCheckResult { if let Some(vi) = self.get_current_scope_var(&ident.inspect()[..]) { self.validate_visibility(ident, vi, namespace)?; Ok(vi.t()) @@ -210,6 +221,7 @@ impl Context { return parent.rec_get_var_t(ident, namespace); } Err(TyCheckError::no_var_error( + self.cfg.input.clone(), line!() as usize, ident.loc(), namespace.into(), @@ -224,7 +236,7 @@ impl Context { obj: &hir::Expr, ident: &Identifier, namespace: &Str, - ) -> TyCheckResult { + ) -> SingleTyCheckResult { let self_t = obj.t(); let name = ident.name.token(); match self.get_attr_t_from_attributive_t(obj, &self_t, ident, namespace) { @@ -249,6 +261,7 @@ impl Context { } for (_, ctx) in self.get_nominal_super_type_ctxs(&self_t).ok_or_else(|| { TyCheckError::no_var_error( + self.cfg.input.clone(), line!() as usize, obj.loc(), self.caused_by(), @@ -271,6 +284,7 @@ impl Context { parent.rec_get_attr_t(obj, ident, namespace) } else { Err(TyCheckError::no_attr_error( + self.cfg.input.clone(), line!() as usize, name.loc(), namespace.into(), @@ -287,7 +301,7 @@ impl Context { t: &Type, ident: &Identifier, namespace: &Str, - ) -> TyCheckResult { + ) -> SingleTyCheckResult { match t { Type::FreeVar(fv) if fv.is_linked() => { self.get_attr_t_from_attributive_t(obj, &fv.crack(), ident, namespace) @@ -310,6 +324,7 @@ impl Context { } else { let t = Type::Record(record.clone()); Err(TyCheckError::no_attr_error( + self.cfg.input.clone(), line!() as usize, ident.loc(), namespace.into(), @@ -330,15 +345,23 @@ impl Context { ValueObj::Type(TypeObj::Generated(gen)) => self .get_gen_t_require_attr_t(gen, &ident.inspect()[..]) .cloned() - .ok_or_else(|| TyCheckError::dummy(line!() as usize)), + .ok_or_else(|| { + TyCheckError::dummy(self.cfg.input.clone(), line!() as usize) + }), ValueObj::Type(TypeObj::Builtin(_t)) => { // FIXME: - Err(TyCheckError::dummy(line!() as usize)) + Err(TyCheckError::dummy( + self.cfg.input.clone(), + line!() as usize, + )) } other => todo!("{other}"), } } else { - Err(TyCheckError::dummy(line!() as usize)) + Err(TyCheckError::dummy( + self.cfg.input.clone(), + line!() as usize, + )) } } } @@ -350,12 +373,13 @@ impl Context { obj: &hir::Expr, method_name: &Option, namespace: &Str, - ) -> TyCheckResult { + ) -> SingleTyCheckResult { if let Some(method_name) = method_name.as_ref() { for (_, ctx) in self .get_nominal_super_type_ctxs(obj.ref_t()) .ok_or_else(|| { TyCheckError::no_var_error( + self.cfg.input.clone(), line!() as usize, obj.loc(), self.caused_by(), @@ -403,6 +427,7 @@ impl Context { } } return Err(TyCheckError::singular_no_attr_error( + self.cfg.input.clone(), line!() as usize, method_name.loc(), namespace.into(), @@ -414,6 +439,7 @@ impl Context { } // TODO: patch Err(TyCheckError::no_attr_error( + self.cfg.input.clone(), line!() as usize, method_name.loc(), namespace.into(), @@ -431,9 +457,10 @@ impl Context { ident: &Identifier, vi: &VarInfo, namespace: &str, - ) -> TyCheckResult<()> { + ) -> SingleTyCheckResult<()> { if ident.vis() != vi.vis { Err(TyCheckError::visibility_error( + self.cfg.input.clone(), line!() as usize, ident.loc(), self.caused_by(), @@ -447,6 +474,7 @@ impl Context { && !namespace.contains(&self.name[..]) { Err(TyCheckError::visibility_error( + self.cfg.input.clone(), line!() as usize, ident.loc(), self.caused_by(), @@ -473,20 +501,26 @@ impl Context { )?; let op = hir::Expr::Accessor(hir::Accessor::private(symbol, t)); self.get_call_t(&op, &None, args, &[], namespace) - .map_err(|e| { + .map_err(|errs| { let op = enum_unwrap!(op, hir::Expr::Accessor:(hir::Accessor::Ident:(_))); let lhs = args[0].expr.clone(); let rhs = args[1].expr.clone(); let bin = hir::BinOp::new(op.name.into_token(), lhs, rhs, op.t); - // HACK: dname.loc()はダミーLocationしか返さないので、エラーならop.loc()で上書きする - let core = ErrorCore::new( - e.core.errno, - e.core.kind, - bin.loc(), - e.core.desc, - e.core.hint, - ); - TyCheckError::new(core, e.caused_by) + TyCheckErrors::new( + errs.into_iter() + .map(|e| { + // HACK: dname.loc()はダミーLocationしか返さないので、エラーならop.loc()で上書きする + let core = ErrorCore::new( + e.core.errno, + e.core.kind, + bin.loc(), + e.core.desc, + e.core.hint, + ); + TyCheckError::new(core, self.cfg.input.clone(), e.caused_by) + }) + .collect(), + ) }) } @@ -505,18 +539,24 @@ impl Context { )?; let op = hir::Expr::Accessor(hir::Accessor::private(symbol, t)); self.get_call_t(&op, &None, args, &[], namespace) - .map_err(|e| { + .map_err(|errs| { let op = enum_unwrap!(op, hir::Expr::Accessor:(hir::Accessor::Ident:(_))); let expr = args[0].expr.clone(); let unary = hir::UnaryOp::new(op.name.into_token(), expr, op.t); - let core = ErrorCore::new( - e.core.errno, - e.core.kind, - unary.loc(), - e.core.desc, - e.core.hint, - ); - TyCheckError::new(core, e.caused_by) + TyCheckErrors::new( + errs.into_iter() + .map(|e| { + let core = ErrorCore::new( + e.core.errno, + e.core.kind, + unary.loc(), + e.core.desc, + e.core.hint, + ); + TyCheckError::new(core, self.cfg.input.clone(), e.caused_by) + }) + .collect(), + ) }) } @@ -573,7 +613,8 @@ impl Context { if (params_len < pos_args.len() || params_len < pos_args.len() + kw_args.len()) && subr.var_params.is_none() { - return Err(TyCheckError::too_many_args_error( + return Err(TyCheckErrors::from(TyCheckError::too_many_args_error( + self.cfg.input.clone(), line!() as usize, callee.loc(), &callee.to_string(), @@ -581,7 +622,7 @@ impl Context { params_len, pos_args.len(), kw_args.len(), - )); + ))); } let mut passed_params = set! {}; let non_default_params_len = if method_name.is_some() { @@ -645,20 +686,22 @@ impl Context { .rev() .map(|pt| pt.name().cloned().unwrap_or(Str::ever(""))) .collect(); - return Err(TyCheckError::args_missing_error( + return Err(TyCheckErrors::from(TyCheckError::args_missing_error( + self.cfg.input.clone(), line!() as usize, callee.loc(), &callee.to_string(), self.caused_by(), missing_len, missing_params, - )); + ))); } Ok(()) } other => { if let Some(method_name) = method_name { - Err(TyCheckError::type_mismatch_error( + Err(TyCheckErrors::from(TyCheckError::type_mismatch_error( + self.cfg.input.clone(), line!() as usize, Location::concat(obj, method_name), self.caused_by(), @@ -667,9 +710,10 @@ impl Context { other, self.get_candidates(other), None, - )) + ))) } else { - Err(TyCheckError::type_mismatch_error( + Err(TyCheckErrors::from(TyCheckError::type_mismatch_error( + self.cfg.input.clone(), line!() as usize, obj.loc(), self.caused_by(), @@ -678,7 +722,7 @@ impl Context { other, self.get_candidates(other), None, - )) + ))) } } } @@ -694,32 +738,39 @@ impl Context { let arg_t = arg.ref_t(); let param_t = ¶m.typ(); self.sub_unify(arg_t, param_t, Some(arg.loc()), None, param.name()) - .map_err(|e| { + .map_err(|errs| { log!(err "semi-unification failed with {callee}\n{arg_t} !<: {param_t}"); - log!(err "errno: {}", e.core.errno); // REVIEW: let name = callee.show_acc().unwrap_or_else(|| "".to_string()); let name = name + "::" + param.name().map(|s| readable_name(&s[..])).unwrap_or(""); - TyCheckError::type_mismatch_error( - line!() as usize, - e.core.loc, - e.caused_by, - &name[..], - param_t, - arg_t, - self.get_candidates(arg_t), - self.get_type_mismatch_hint(param_t, arg_t), + TyCheckErrors::new( + errs.into_iter() + .map(|e| { + TyCheckError::type_mismatch_error( + self.cfg.input.clone(), + line!() as usize, + e.core.loc, + e.caused_by, + &name[..], + param_t, + arg_t, + self.get_candidates(arg_t), + self.get_type_mismatch_hint(param_t, arg_t), + ) + }) + .collect(), ) })?; if let Some(name) = param.name() { if passed_params.contains(name) { - return Err(TyCheckError::multiple_args_error( + return Err(TyCheckErrors::from(TyCheckError::multiple_args_error( + self.cfg.input.clone(), line!() as usize, callee.loc(), &callee.to_string(), self.caused_by(), name, - )); + ))); } else { passed_params.insert(name.clone()); } @@ -736,21 +787,27 @@ impl Context { let arg_t = arg.ref_t(); let param_t = ¶m.typ(); self.sub_unify(arg_t, param_t, Some(arg.loc()), None, param.name()) - .map_err(|e| { + .map_err(|errs| { log!(err "semi-unification failed with {callee}\n{arg_t} !<: {param_t}"); - log!(err "errno: {}", e.core.errno); // REVIEW: let name = callee.show_acc().unwrap_or_else(|| "".to_string()); let name = name + "::" + param.name().map(|s| readable_name(&s[..])).unwrap_or(""); - TyCheckError::type_mismatch_error( - line!() as usize, - e.core.loc, - e.caused_by, - &name[..], - param_t, - arg_t, - self.get_candidates(arg_t), - self.get_type_mismatch_hint(param_t, arg_t), + TyCheckErrors::new( + errs.into_iter() + .map(|e| { + TyCheckError::type_mismatch_error( + self.cfg.input.clone(), + line!() as usize, + e.core.loc, + e.caused_by, + &name[..], + param_t, + arg_t, + self.get_candidates(arg_t), + self.get_type_mismatch_hint(param_t, arg_t), + ) + }) + .collect(), ) }) } @@ -765,13 +822,14 @@ impl Context { let arg_t = arg.expr.ref_t(); let kw_name = arg.keyword.inspect(); if passed_params.contains(&kw_name[..]) { - return Err(TyCheckError::multiple_args_error( + return Err(TyCheckErrors::from(TyCheckError::multiple_args_error( + self.cfg.input.clone(), line!() as usize, callee.loc(), &callee.to_string(), self.caused_by(), arg.keyword.inspect(), - )); + ))); } else { passed_params.insert(kw_name.clone()); } @@ -780,31 +838,38 @@ impl Context { .find(|pt| pt.name().unwrap() == kw_name) { self.sub_unify(arg_t, pt.typ(), Some(arg.loc()), None, Some(kw_name)) - .map_err(|e| { + .map_err(|errs| { log!(err "semi-unification failed with {callee}\n{arg_t} !<: {}", pt.typ()); - log!(err "errno: {}", e.core.errno); // REVIEW: let name = callee.show_acc().unwrap_or_else(|| "".to_string()); let name = name + "::" + readable_name(kw_name); - TyCheckError::type_mismatch_error( - line!() as usize, - e.core.loc, - e.caused_by, - &name[..], - pt.typ(), - arg_t, - self.get_candidates(arg_t), - self.get_type_mismatch_hint(pt.typ(), arg_t), + TyCheckErrors::new( + errs.into_iter() + .map(|e| { + TyCheckError::type_mismatch_error( + self.cfg.input.clone(), + line!() as usize, + e.core.loc, + e.caused_by, + &name[..], + pt.typ(), + arg_t, + self.get_candidates(arg_t), + self.get_type_mismatch_hint(pt.typ(), arg_t), + ) + }) + .collect(), ) })?; } else { - return Err(TyCheckError::unexpected_kw_arg_error( + return Err(TyCheckErrors::from(TyCheckError::unexpected_kw_arg_error( + self.cfg.input.clone(), line!() as usize, arg.keyword.loc(), &callee.to_string(), self.caused_by(), kw_name, - )); + ))); } Ok(()) } @@ -845,7 +910,11 @@ impl Context { Ok(res) } - pub(crate) fn get_const_local(&self, name: &Token, namespace: &Str) -> TyCheckResult { + pub(crate) fn get_const_local( + &self, + name: &Token, + namespace: &Str, + ) -> SingleTyCheckResult { if let Some(obj) = self.consts.get(name.inspect()) { Ok(obj.clone()) } else { @@ -853,6 +922,7 @@ impl Context { return parent.get_const_local(name, namespace); } Err(TyCheckError::no_var_error( + self.cfg.input.clone(), line!() as usize, name.loc(), namespace.into(), @@ -867,10 +937,11 @@ impl Context { obj: &hir::Expr, name: &Token, namespace: &Str, - ) -> TyCheckResult { + ) -> SingleTyCheckResult { let self_t = obj.ref_t(); for (_, ctx) in self.get_nominal_super_type_ctxs(self_t).ok_or_else(|| { TyCheckError::no_var_error( + self.cfg.input.clone(), line!() as usize, obj.loc(), self.caused_by(), @@ -887,6 +958,7 @@ impl Context { parent._get_const_attr(obj, name, namespace) } else { Err(TyCheckError::no_attr_error( + self.cfg.input.clone(), line!() as usize, name.loc(), namespace.into(), diff --git a/compiler/erg_compiler/context/instantiate.rs b/compiler/erg_compiler/context/instantiate.rs index 09c1d9dd..c75e56d0 100644 --- a/compiler/erg_compiler/context/instantiate.rs +++ b/compiler/erg_compiler/context/instantiate.rs @@ -27,7 +27,7 @@ use Type::*; use crate::context::eval::eval_lit; use crate::context::{Context, RegistrationMode}; -use crate::error::{TyCheckError, TyCheckResult}; +use crate::error::{SingleTyCheckResult, TyCheckError, TyCheckErrors, TyCheckResult}; use crate::hir; use RegistrationMode::*; @@ -524,7 +524,7 @@ impl Context { } other if simple.args.is_empty() => { if let Some(tv_ctx) = tv_ctx { - Self::instantiate_t(mono_q(Str::rc(other)), tv_ctx, simple.loc()) + self.instantiate_t(mono_q(Str::rc(other)), tv_ctx, simple.loc()) } else if let Some(decl_t) = opt_decl_t { Ok(decl_t.typ().clone()) } else { @@ -532,13 +532,14 @@ impl Context { if let Some((defined_t, _)) = self.get_nominal_type_ctx(&typ) { Ok(defined_t.clone()) } else { - Err(TyCheckError::no_var_error( + Err(TyCheckErrors::from(TyCheckError::no_var_error( + self.cfg.input.clone(), line!() as usize, simple.loc(), self.caused_by(), other, self.get_similar_name(other), - )) + ))) } } } @@ -569,7 +570,7 @@ impl Context { pub(crate) fn instantiate_const_expr_as_type( &self, expr: &ast::ConstExpr, - ) -> TyCheckResult { + ) -> SingleTyCheckResult { match expr { ast::ConstExpr::Accessor(ast::ConstAccessor::Local(name)) => { Ok(mono(self.mod_name(), name.inspect())) @@ -600,7 +601,9 @@ impl Context { mode: RegistrationMode, ) -> TyCheckResult { match spec { - TypeSpec::PreDeclTy(predecl) => self.instantiate_predecl_t(predecl, opt_decl_t, tv_ctx), + TypeSpec::PreDeclTy(predecl) => { + Ok(self.instantiate_predecl_t(predecl, opt_decl_t, tv_ctx)?) + } // TODO: Flatten TypeSpec::And(lhs, rhs) => Ok(and( self.instantiate_typespec(lhs, opt_decl_t, tv_ctx, mode)?, @@ -723,6 +726,7 @@ impl Context { } fn instantiate_tp( + &self, quantified: TyParam, tv_ctx: &mut TyVarContext, loc: Location, @@ -734,29 +738,30 @@ impl Context { } else if let Some(t) = tv_ctx.get_tyvar(&n) { Ok(TyParam::t(t.clone())) } else { - Err(TyCheckError::tyvar_not_defined_error( + Err(TyCheckErrors::from(TyCheckError::tyvar_not_defined_error( + self.cfg.input.clone(), line!() as usize, &n, loc, AtomicStr::ever("?"), - )) + ))) } } TyParam::UnaryOp { op, val } => { - let res = Self::instantiate_tp(*val, tv_ctx, loc)?; + let res = self.instantiate_tp(*val, tv_ctx, loc)?; Ok(TyParam::unary(op, res)) } TyParam::BinOp { op, lhs, rhs } => { - let lhs = Self::instantiate_tp(*lhs, tv_ctx, loc)?; - let rhs = Self::instantiate_tp(*rhs, tv_ctx, loc)?; + let lhs = self.instantiate_tp(*lhs, tv_ctx, loc)?; + let rhs = self.instantiate_tp(*rhs, tv_ctx, loc)?; Ok(TyParam::bin(op, lhs, rhs)) } TyParam::Type(t) => { - let t = Self::instantiate_t(*t, tv_ctx, loc)?; + let t = self.instantiate_t(*t, tv_ctx, loc)?; Ok(TyParam::t(t)) } TyParam::FreeVar(fv) if fv.is_linked() => { - Self::instantiate_tp(fv.crack().clone(), tv_ctx, loc) + self.instantiate_tp(fv.crack().clone(), tv_ctx, loc) } p @ (TyParam::Value(_) | TyParam::Mono(_) | TyParam::FreeVar(_)) => Ok(p), other => todo!("{other}"), @@ -765,6 +770,7 @@ impl Context { /// 'T -> ?T (quantified to free) pub(crate) fn instantiate_t( + &self, unbound: Type, tv_ctx: &mut TyVarContext, loc: Location, @@ -784,17 +790,18 @@ impl Context { ) } } else { - Err(TyCheckError::tyvar_not_defined_error( + Err(TyCheckErrors::from(TyCheckError::tyvar_not_defined_error( + self.cfg.input.clone(), line!() as usize, &n, loc, AtomicStr::ever("?"), - )) + ))) } } PolyQVar { name, mut params } => { for param in params.iter_mut() { - *param = Self::instantiate_tp(mem::take(param), tv_ctx, loc)?; + *param = self.instantiate_tp(mem::take(param), tv_ctx, loc)?; } Ok(poly_q(name, params)) } @@ -802,7 +809,7 @@ impl Context { let mut new_preds = set! {}; for mut pred in refine.preds.into_iter() { for tp in pred.typarams_mut() { - *tp = Self::instantiate_tp(mem::take(tp), tv_ctx, loc)?; + *tp = self.instantiate_tp(mem::take(tp), tv_ctx, loc)?; } new_preds.insert(pred); } @@ -811,16 +818,16 @@ impl Context { } Subr(mut subr) => { for pt in subr.non_default_params.iter_mut() { - *pt.typ_mut() = Self::instantiate_t(mem::take(pt.typ_mut()), tv_ctx, loc)?; + *pt.typ_mut() = self.instantiate_t(mem::take(pt.typ_mut()), tv_ctx, loc)?; } if let Some(var_args) = subr.var_params.as_mut() { *var_args.typ_mut() = - Self::instantiate_t(mem::take(var_args.typ_mut()), tv_ctx, loc)?; + self.instantiate_t(mem::take(var_args.typ_mut()), tv_ctx, loc)?; } for pt in subr.default_params.iter_mut() { - *pt.typ_mut() = Self::instantiate_t(mem::take(pt.typ_mut()), tv_ctx, loc)?; + *pt.typ_mut() = self.instantiate_t(mem::take(pt.typ_mut()), tv_ctx, loc)?; } - let return_t = Self::instantiate_t(*subr.return_t, tv_ctx, loc)?; + let return_t = self.instantiate_t(*subr.return_t, tv_ctx, loc)?; Ok(subr_t( subr.kind, subr.non_default_params, @@ -831,39 +838,39 @@ impl Context { } Record(mut dict) => { for v in dict.values_mut() { - *v = Self::instantiate_t(mem::take(v), tv_ctx, loc)?; + *v = self.instantiate_t(mem::take(v), tv_ctx, loc)?; } Ok(Type::Record(dict)) } Ref(t) => { - let t = Self::instantiate_t(*t, tv_ctx, loc)?; + let t = self.instantiate_t(*t, tv_ctx, loc)?; Ok(ref_(t)) } RefMut { before, after } => { - let before = Self::instantiate_t(*before, tv_ctx, loc)?; + let before = self.instantiate_t(*before, tv_ctx, loc)?; let after = after - .map(|aft| Self::instantiate_t(*aft, tv_ctx, loc)) + .map(|aft| self.instantiate_t(*aft, tv_ctx, loc)) .transpose()?; Ok(ref_mut(before, after)) } MonoProj { lhs, rhs } => { - let lhs = Self::instantiate_t(*lhs, tv_ctx, loc)?; + let lhs = self.instantiate_t(*lhs, tv_ctx, loc)?; Ok(mono_proj(lhs, rhs)) } Poly { name, mut params } => { for param in params.iter_mut() { - *param = Self::instantiate_tp(mem::take(param), tv_ctx, loc)?; + *param = self.instantiate_tp(mem::take(param), tv_ctx, loc)?; } Ok(poly(name, params)) } Quantified(_) => { panic!("a quantified type should not be instantiated, instantiate the inner type") } - FreeVar(fv) if fv.is_linked() => Self::instantiate_t(fv.crack().clone(), tv_ctx, loc), + FreeVar(fv) if fv.is_linked() => self.instantiate_t(fv.crack().clone(), tv_ctx, loc), FreeVar(fv) => { let (sub, sup) = fv.get_bound_types().unwrap(); - let sub = Self::instantiate_t(sub, tv_ctx, loc)?; - let sup = Self::instantiate_t(sup, tv_ctx, loc)?; + let sub = self.instantiate_t(sub, tv_ctx, loc)?; + let sup = self.instantiate_t(sup, tv_ctx, loc)?; let new_constraint = Constraint::new_sandwiched(sub, sup, fv.cyclicity()); fv.update_constraint(new_constraint); Ok(FreeVar(fv)) @@ -877,7 +884,7 @@ impl Context { match quantified { Quantified(quant) => { let mut tv_ctx = TyVarContext::new(self.level, quant.bounds, self); - let t = Self::instantiate_t(*quant.unbound_callable, &mut tv_ctx, callee.loc())?; + let t = self.instantiate_t(*quant.unbound_callable, &mut tv_ctx, callee.loc())?; match &t { Type::Subr(subr) => { if let Some(self_t) = subr.self_t() { diff --git a/compiler/erg_compiler/context/mod.rs b/compiler/erg_compiler/context/mod.rs index 3228b8e9..5adff82e 100644 --- a/compiler/erg_compiler/context/mod.rs +++ b/compiler/erg_compiler/context/mod.rs @@ -18,6 +18,7 @@ use std::mem; use std::option::Option; // conflicting to Type::Option use erg_common::astr::AtomicStr; +use erg_common::config::ErgConfig; use erg_common::dict::Dict; use erg_common::error::Location; use erg_common::impl_display_from_debug; @@ -37,7 +38,7 @@ use erg_parser::ast; use erg_parser::token::Token; use crate::context::instantiate::ConstTemplate; -use crate::error::{TyCheckError, TyCheckErrors, TyCheckResult}; +use crate::error::{SingleTyCheckResult, TyCheckError, TyCheckErrors, TyCheckResult}; use crate::mod_cache::SharedModuleCache; use crate::varinfo::{Mutability, ParamIdx, VarInfo, VarKind}; use Visibility::*; @@ -293,6 +294,7 @@ impl ImportKind { #[derive(Debug, Clone)] pub struct Context { pub(crate) name: Str, + pub(crate) cfg: ErgConfig, pub(crate) kind: ContextKind, // Type bounds & Predicates (if the context kind is Subroutine) // ユーザー定義APIでのみ使う @@ -350,6 +352,7 @@ impl Default for Context { fn default() -> Self { Self::new( "".into(), + ErgConfig::default(), ContextKind::Dummy, vec![], None, @@ -379,9 +382,11 @@ impl fmt::Display for Context { } impl Context { + #[allow(clippy::too_many_arguments)] #[inline] pub fn new( name: Str, + cfg: ErgConfig, kind: ContextKind, params: Vec, outer: Option, @@ -389,18 +394,29 @@ impl Context { py_mod_cache: Option, level: usize, ) -> Self { - Self::with_capacity(name, kind, params, outer, 0, mod_cache, py_mod_cache, level) + Self::with_capacity( + name, + cfg, + kind, + params, + outer, + mod_cache, + py_mod_cache, + 0, + level, + ) } #[allow(clippy::too_many_arguments)] pub fn with_capacity( name: Str, + cfg: ErgConfig, kind: ContextKind, params: Vec, outer: Option, - capacity: usize, mod_cache: Option, py_mod_cache: Option, + capacity: usize, level: usize, ) -> Self { let mut params_ = Vec::new(); @@ -422,6 +438,7 @@ impl Context { } Self { name, + cfg, kind, bounds: vec![], preds: vec![], @@ -448,146 +465,287 @@ impl Context { #[inline] pub fn mono( name: Str, + cfg: ErgConfig, kind: ContextKind, outer: Option, mod_cache: Option, py_mod_cache: Option, level: usize, ) -> Self { - Self::with_capacity(name, kind, vec![], outer, 0, mod_cache, py_mod_cache, level) + Self::new( + name, + cfg, + kind, + vec![], + outer, + mod_cache, + py_mod_cache, + level, + ) } + #[allow(clippy::too_many_arguments)] #[inline] pub fn poly( name: Str, + cfg: ErgConfig, kind: ContextKind, params: Vec, outer: Option, mod_cache: Option, py_mod_cache: Option, + capacity: usize, level: usize, ) -> Self { - Self::with_capacity(name, kind, params, outer, 0, mod_cache, py_mod_cache, level) + Self::with_capacity( + name, + cfg, + kind, + params, + outer, + mod_cache, + py_mod_cache, + capacity, + level, + ) } pub fn poly_trait>( name: S, params: Vec, + cfg: ErgConfig, mod_cache: Option, py_mod_cache: Option, + capacity: usize, level: usize, ) -> Self { let name = name.into(); Self::poly( name, + cfg, ContextKind::Trait, params, None, mod_cache, py_mod_cache, + capacity, level, ) } + #[inline] + pub fn builtin_poly_trait>( + name: S, + params: Vec, + capacity: usize, + ) -> Self { + Self::poly_trait( + name, + params, + ErgConfig::default(), + None, + None, + capacity, + Self::TOP_LEVEL, + ) + } + pub fn poly_class>( name: S, params: Vec, + cfg: ErgConfig, mod_cache: Option, py_mod_cache: Option, + capacity: usize, level: usize, ) -> Self { let name = name.into(); Self::poly( name, + cfg, ContextKind::Class, params, None, mod_cache, py_mod_cache, + capacity, level, ) } + #[inline] + pub fn builtin_poly_class>( + name: S, + params: Vec, + capacity: usize, + ) -> Self { + Self::poly_class( + name, + params, + ErgConfig::default(), + None, + None, + capacity, + Self::TOP_LEVEL, + ) + } + #[inline] pub fn mono_trait>( name: S, + cfg: ErgConfig, mod_cache: Option, py_mod_cache: Option, + capacity: usize, level: usize, ) -> Self { - Self::poly_trait(name, vec![], mod_cache, py_mod_cache, level) + Self::poly_trait(name, vec![], cfg, mod_cache, py_mod_cache, capacity, level) + } + + #[inline] + pub fn builtin_mono_trait>(name: S, capacity: usize) -> Self { + Self::mono_trait( + name, + ErgConfig::default(), + None, + None, + capacity, + Self::TOP_LEVEL, + ) } #[inline] pub fn mono_class>( name: S, + cfg: ErgConfig, mod_cache: Option, py_mod_cache: Option, + capacity: usize, level: usize, ) -> Self { - Self::poly_class(name, vec![], mod_cache, py_mod_cache, level) + Self::poly_class(name, vec![], cfg, mod_cache, py_mod_cache, capacity, level) + } + + #[inline] + pub fn builtin_mono_class>(name: S, capacity: usize) -> Self { + Self::mono_class( + name, + ErgConfig::default(), + None, + None, + capacity, + Self::TOP_LEVEL, + ) } #[inline] pub fn methods>( name: S, + cfg: ErgConfig, mod_cache: Option, py_mod_cache: Option, + capacity: usize, level: usize, ) -> Self { Self::with_capacity( name.into(), + cfg, ContextKind::MethodDefs, vec![], None, - 2, mod_cache, py_mod_cache, + capacity, level, ) } + #[inline] + pub fn builtin_methods>(name: S, capacity: usize) -> Self { + Self::methods( + name, + ErgConfig::default(), + None, + None, + capacity, + Self::TOP_LEVEL, + ) + } + + #[allow(clippy::too_many_arguments)] #[inline] pub fn poly_patch>( name: S, + base: Type, params: Vec, + cfg: ErgConfig, mod_cache: Option, py_mod_cache: Option, + capacity: usize, level: usize, ) -> Self { Self::poly( name.into(), - ContextKind::Trait, + cfg, + ContextKind::Patch(base), params, None, mod_cache, py_mod_cache, + capacity, level, ) } + #[inline] + pub fn builtin_poly_patch>( + name: S, + base: Type, + params: Vec, + capacity: usize, + ) -> Self { + Self::poly_patch( + name, + base, + params, + ErgConfig::default(), + None, + None, + capacity, + Self::TOP_LEVEL, + ) + } + #[inline] pub fn module( name: Str, + cfg: ErgConfig, mod_cache: Option, py_mod_cache: Option, capacity: usize, ) -> Self { Self::with_capacity( name, + cfg, ContextKind::Module, vec![], None, - capacity, mod_cache, py_mod_cache, + capacity, Self::TOP_LEVEL, ) } + #[inline] + pub fn builtin_module>(name: S, capacity: usize) -> Self { + Self::module(name.into(), ErgConfig::default(), None, None, capacity) + } + #[inline] pub fn instant( name: Str, + cfg: ErgConfig, capacity: usize, mod_cache: Option, py_mod_cache: Option, @@ -595,12 +753,13 @@ impl Context { ) -> Self { Self::with_capacity( name, + cfg, ContextKind::Instant, vec![], Some(outer), - capacity, mod_cache, py_mod_cache, + capacity, Self::TOP_LEVEL, ) } @@ -679,6 +838,7 @@ impl Context { let mut uninited_errs = TyCheckErrors::empty(); for (name, vi) in self.decls.iter() { uninited_errs.push(TyCheckError::uninitialized_error( + self.cfg.input.clone(), line!() as usize, name.loc(), self.caused_by(), @@ -706,7 +866,7 @@ impl Context { vars } - pub fn get_var_info(&self, name: &str) -> TyCheckResult<(&VarName, &VarInfo)> { + pub fn get_var_info(&self, name: &str) -> SingleTyCheckResult<(&VarName, &VarInfo)> { if let Some(info) = self.get_local_kv(name) { Ok(info) } else { @@ -714,6 +874,7 @@ impl Context { return parent.get_var_info(name); } Err(TyCheckError::no_var_error( + self.cfg.input.clone(), line!() as usize, Location::Unknown, self.caused_by(), diff --git a/compiler/erg_compiler/context/register.rs b/compiler/erg_compiler/context/register.rs index a772ba7f..8471d95a 100644 --- a/compiler/erg_compiler/context/register.rs +++ b/compiler/erg_compiler/context/register.rs @@ -2,7 +2,6 @@ use std::option::Option; use std::path::PathBuf; // conflicting to Type::Option use erg_common::config::{ErgConfig, Input}; -use erg_common::error::MultiErrorDisplay; use erg_common::levenshtein::get_similar_name; use erg_common::traits::{Locational, Stream}; use erg_common::vis::Visibility; @@ -21,7 +20,9 @@ use Type::*; use crate::build_hir::HIRBuilder; use crate::context::{ClassDefType, Context, DefaultInfo, RegistrationMode, TraitInstance}; use crate::error::readable_name; -use crate::error::{TyCheckError, TyCheckResult}; +use crate::error::{ + CompileResult, SingleTyCheckResult, TyCheckError, TyCheckErrors, TyCheckResult, +}; use crate::hir::{self, Literal}; use crate::mod_cache::SharedModuleCache; use crate::varinfo::{Mutability, ParamIdx, VarInfo, VarKind}; @@ -73,12 +74,13 @@ impl Context { let kind = id.map_or(VarKind::Declared, VarKind::Defined); let sig_t = self.instantiate_var_sig_t(sig.t_spec.as_ref(), opt_t, PreRegister)?; if let Some(_decl) = self.decls.remove(&ident.name) { - Err(TyCheckError::duplicate_decl_error( + Err(TyCheckErrors::from(TyCheckError::duplicate_decl_error( + self.cfg.input.clone(), line!() as usize, sig.loc(), self.caused_by(), ident.name.inspect(), - )) + ))) } else { self.decls.insert( ident.name.clone(), @@ -113,12 +115,13 @@ impl Context { .collect(); let vi = VarInfo::new(t, muty, vis, kind, Some(comptime_decos)); if let Some(_decl) = self.decls.remove(name) { - Err(TyCheckError::duplicate_decl_error( + Err(TyCheckErrors::from(TyCheckError::duplicate_decl_error( + self.cfg.input.clone(), line!() as usize, sig.loc(), self.caused_by(), name, - )) + ))) } else { self.decls.insert(sig.ident.name.clone(), vi); Ok(()) @@ -167,12 +170,13 @@ impl Context { .registered_info(name.inspect(), name.is_const()) .is_some() { - Err(TyCheckError::reassign_error( + Err(TyCheckErrors::from(TyCheckError::reassign_error( + self.cfg.input.clone(), line!() as usize, name.loc(), self.caused_by(), name.inspect(), - )) + ))) } else { // ok, not defined let spec_t = @@ -212,12 +216,13 @@ impl Context { .registered_info(name.inspect(), name.is_const()) .is_some() { - Err(TyCheckError::reassign_error( + Err(TyCheckErrors::from(TyCheckError::reassign_error( + self.cfg.input.clone(), line!() as usize, name.loc(), self.caused_by(), name.inspect(), - )) + ))) } else { // ok, not defined let spec_t = @@ -257,12 +262,13 @@ impl Context { .registered_info(name.inspect(), name.is_const()) .is_some() { - Err(TyCheckError::reassign_error( + Err(TyCheckErrors::from(TyCheckError::reassign_error( + self.cfg.input.clone(), line!() as usize, name.loc(), self.caused_by(), name.inspect(), - )) + ))) } else { // ok, not defined let spec_t = @@ -376,14 +382,21 @@ impl Context { let default_params = t.default_params().unwrap(); if let Some(spec_ret_t) = t.return_t() { self.sub_unify(body_t, spec_ret_t, None, Some(sig.loc()), None) - .map_err(|e| { - TyCheckError::return_type_error( - line!() as usize, - e.core.loc, - e.caused_by, - readable_name(name.inspect()), - spec_ret_t, - body_t, + .map_err(|errs| { + TyCheckErrors::new( + errs.into_iter() + .map(|e| { + TyCheckError::return_type_error( + self.cfg.input.clone(), + line!() as usize, + e.core.loc, + e.caused_by, + readable_name(name.inspect()), + spec_ret_t, + body_t, + ) + }) + .collect(), ) })?; } @@ -413,14 +426,15 @@ impl Context { } if let Some(vi) = self.decls.remove(name) { if !self.supertype_of(&vi.t, &found_t) { - return Err(TyCheckError::violate_decl_error( + return Err(TyCheckErrors::from(TyCheckError::violate_decl_error( + self.cfg.input.clone(), line!() as usize, sig.loc(), self.caused_by(), name.inspect(), &vi.t, &found_t, - )); + ))); } } let comptime_decos = sig @@ -576,9 +590,10 @@ impl Context { &mut self, ident: &Identifier, obj: ValueObj, - ) -> TyCheckResult<()> { + ) -> SingleTyCheckResult<()> { if self.rec_get_const_obj(ident.inspect()).is_some() { Err(TyCheckError::reassign_error( + self.cfg.input.clone(), line!() as usize, ident.loc(), self.caused_by(), @@ -615,14 +630,18 @@ impl Context { // let super_traits = gen.impls.iter().map(|to| to.typ().clone()).collect(); let mut ctx = Self::mono_class( gen.t.name(), + self.cfg.clone(), self.mod_cache.clone(), self.py_mod_cache.clone(), + 2, self.level, ); let mut methods = Self::methods( gen.t.name(), + self.cfg.clone(), self.mod_cache.clone(), self.py_mod_cache.clone(), + 2, self.level, ); let require = gen.require_or_sup.typ().clone(); @@ -643,8 +662,10 @@ impl Context { // let super_traits = gen.impls.iter().map(|to| to.typ().clone()).collect(); let mut ctx = Self::mono_class( gen.t.name(), + self.cfg.clone(), self.mod_cache.clone(), self.py_mod_cache.clone(), + 2, self.level, ); for sup in super_classes.into_iter() { @@ -653,8 +674,10 @@ impl Context { } let mut methods = Self::methods( gen.t.name(), + self.cfg.clone(), self.mod_cache.clone(), self.py_mod_cache.clone(), + 2, self.level, ); if let Some(sup) = self.rec_get_const_obj(&gen.require_or_sup.typ().name()) { @@ -693,8 +716,10 @@ impl Context { if gen.t.is_monomorphic() { let mut ctx = Self::mono_trait( gen.t.name(), + self.cfg.clone(), self.mod_cache.clone(), self.py_mod_cache.clone(), + 2, self.level, ); let require = enum_unwrap!(gen.require_or_sup.as_ref(), TypeObj::Builtin:(Type::Record:(_))); @@ -719,8 +744,10 @@ impl Context { // let super_traits = gen.impls.iter().map(|to| to.typ().clone()).collect(); let mut ctx = Self::mono_trait( gen.t.name(), + self.cfg.clone(), self.mod_cache.clone(), self.py_mod_cache.clone(), + 2, self.level, ); let additional = gen.additional.as_ref().map(|additional| enum_unwrap!(additional.as_ref(), TypeObj::Builtin:(Type::Record:(_)))); @@ -791,20 +818,20 @@ impl Context { pub(crate) fn import_mod( &mut self, kind: ImportKind, - current_input: Input, var_name: &VarName, mod_name: &hir::Expr, - ) -> TyCheckResult<()> { + ) -> CompileResult<()> { match mod_name { hir::Expr::Lit(lit) => { if self.subtype_of(&lit.value.class(), &Str) { if kind.is_erg_import() { - self.import_erg_mod(current_input, var_name, lit)?; + self.import_erg_mod(var_name, lit)?; } else { - self.import_py_mod(current_input, var_name, lit)?; + self.import_py_mod(var_name, lit)?; } } else { - return Err(TyCheckError::type_mismatch_error( + return Err(TyCheckErrors::from(TyCheckError::type_mismatch_error( + self.cfg.input.clone(), line!() as usize, mod_name.loc(), self.caused_by(), @@ -813,59 +840,46 @@ impl Context { mod_name.ref_t(), self.get_candidates(mod_name.ref_t()), self.get_type_mismatch_hint(&Str, mod_name.ref_t()), - )); + ))); } } - _ => { - return Err(TyCheckError::feature_error( - line!() as usize, + _other => { + return Err(TyCheckErrors::from(TyCheckError::feature_error( + self.cfg.input.clone(), mod_name.loc(), "non-literal importing", self.caused_by(), - )) + ))) } } Ok(()) } - fn import_erg_mod( - &mut self, - current_input: Input, - var_name: &VarName, - lit: &Literal, - ) -> TyCheckResult<()> { + fn import_erg_mod(&mut self, var_name: &VarName, lit: &Literal) -> CompileResult<()> { let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str); let mod_cache = self.mod_cache.as_ref().unwrap(); let py_mod_cache = self.py_mod_cache.as_ref().unwrap(); #[allow(clippy::match_single_binding)] match &__name__[..] { // TODO: erg builtin modules - _ => self.import_user_erg_mod( - current_input, - var_name, - __name__, - lit, - mod_cache, - py_mod_cache, - )?, + _ => self.import_user_erg_mod(var_name, __name__, lit, mod_cache, py_mod_cache)?, } Ok(()) } fn import_user_erg_mod( &self, - current_input: Input, var_name: &VarName, __name__: Str, name_lit: &Literal, mod_cache: &SharedModuleCache, py_mod_cache: &SharedModuleCache, - ) -> TyCheckResult<()> { + ) -> CompileResult<()> { if let Some((_, entry)) = mod_cache.get_by_name(&__name__) { mod_cache.register_alias(var_name.clone(), entry); return Ok(()); } - let mut dir = if let Input::File(mut path) = current_input { + let mut dir = if let Input::File(mut path) = self.cfg.input.clone() { path.pop(); path } else { @@ -875,7 +889,8 @@ impl Context { let path = match dir.canonicalize() { Ok(path) => path, Err(err) => { - return Err(TyCheckError::import_error( + let err = TyCheckErrors::from(TyCheckError::import_error( + self.cfg.input.clone(), line!() as usize, err.to_string(), name_lit.loc(), @@ -888,6 +903,7 @@ impl Context { .get_similar_name(&__name__) }), )); + return Err(err); } }; let cfg = ErgConfig::with_path(path); @@ -902,19 +918,17 @@ impl Context { Ok(hir) => { mod_cache.register(var_name.clone(), Some(hir), builder.pop_ctx()); } - Err(errs) => { - errs.fmt_all_stderr(); + Err((maybe_hir, errs)) => { + if let Some(hir) = maybe_hir { + mod_cache.register(var_name.clone(), Some(hir), builder.pop_ctx()); + } + return Err(errs); } } Ok(()) } - fn import_py_mod( - &mut self, - current_input: Input, - var_name: &VarName, - lit: &Literal, - ) -> TyCheckResult<()> { + fn import_py_mod(&mut self, var_name: &VarName, lit: &Literal) -> CompileResult<()> { let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str); let mod_cache = self.mod_cache.as_ref().unwrap(); match &__name__[..] { @@ -939,7 +953,7 @@ impl Context { "time" => { mod_cache.register(var_name.clone(), None, Self::init_py_time_mod()); } - _ => self.import_user_py_mod(current_input, var_name, lit)?, + _ => self.import_user_py_mod(var_name, lit)?, } Ok(()) } @@ -952,19 +966,14 @@ impl Context { .map(Str::rc) } - fn import_user_py_mod( - &self, - current_input: Input, - var_name: &VarName, - lit: &Literal, - ) -> TyCheckResult<()> { + fn import_user_py_mod(&self, var_name: &VarName, lit: &Literal) -> CompileResult<()> { let __name__ = enum_unwrap!(lit.value.clone(), ValueObj::Str); let py_mod_cache = self.py_mod_cache.as_ref().unwrap(); if let Some((_, entry)) = py_mod_cache.get_by_name(&__name__) { py_mod_cache.register_alias(var_name.clone(), entry); return Ok(()); } - let mut dir = if let Input::File(mut path) = current_input { + let mut dir = if let Input::File(mut path) = self.cfg.input.clone() { path.pop(); path } else { @@ -974,7 +983,8 @@ impl Context { let path = match dir.canonicalize() { Ok(path) => path, Err(err) => { - return Err(TyCheckError::import_error( + let err = TyCheckError::import_error( + self.cfg.input.clone(), line!() as usize, err.to_string(), lit.loc(), @@ -986,7 +996,8 @@ impl Context { .unwrap() .get_similar_name(&__name__) }), - )); + ); + return Err(TyCheckErrors::from(err)); } }; let cfg = ErgConfig::with_path(path); @@ -1001,8 +1012,11 @@ impl Context { Ok(hir) => { py_mod_cache.register(var_name.clone(), Some(hir), builder.pop_ctx()); } - Err(errs) => { - errs.fmt_all_stderr(); + Err((maybe_hir, errs)) => { + if let Some(hir) = maybe_hir { + py_mod_cache.register(var_name.clone(), Some(hir), builder.pop_ctx()); + } + return Err(errs); } } Ok(()) diff --git a/compiler/erg_compiler/context/test.rs b/compiler/erg_compiler/context/test.rs index 84b1590e..07b528e7 100644 --- a/compiler/erg_compiler/context/test.rs +++ b/compiler/erg_compiler/context/test.rs @@ -56,16 +56,18 @@ impl Context { println!("quantified : {quantified}"); let mut tv_ctx = TyVarContext::new(self.level + 1, bounds, self); println!("tv_ctx: {tv_ctx}"); - let inst = - Self::instantiate_t(unbound_t, &mut tv_ctx, Location::Unknown).map_err(|_| ())?; + let inst = self + .instantiate_t(unbound_t, &mut tv_ctx, Location::Unknown) + .map_err(|_| ())?; println!("inst: {inst}"); let quantified_again = self.generalize_t(inst); println!("quantified_again: {quantified_again}"); assert_eq!(quantified, quantified_again); let unbound_t = *enum_unwrap!(quantified_again, Type::Quantified).unbound_callable; // 同じtv_ctxで2回instantiateしないこと - let inst = - Self::instantiate_t(unbound_t, &mut tv_ctx, Location::Unknown).map_err(|_| ())?; // (?T(<: Eq('T))[2]) -> ?T(<: Eq('T))[2] + let inst = self + .instantiate_t(unbound_t, &mut tv_ctx, Location::Unknown) + .map_err(|_| ())?; // (?T(<: Eq('T))[2]) -> ?T(<: Eq('T))[2] println!("inst: {inst}"); let quantified_again = self.generalize_t(inst); println!("quantified_again: {quantified_again}"); diff --git a/compiler/erg_compiler/context/tyvar.rs b/compiler/erg_compiler/context/tyvar.rs index 839b5ce3..606913c1 100644 --- a/compiler/erg_compiler/context/tyvar.rs +++ b/compiler/erg_compiler/context/tyvar.rs @@ -16,7 +16,7 @@ use erg_type::{HasType, Predicate, TyBound, Type}; use crate::context::{Context, Variance}; // use crate::context::instantiate::TyVarContext; -use crate::error::{TyCheckError, TyCheckResult}; +use crate::error::{SingleTyCheckResult, TyCheckError, TyCheckErrors, TyCheckResult}; use crate::hir; use Predicate as Pred; @@ -203,15 +203,17 @@ impl Context { } } - fn deref_tp(&self, tp: TyParam, loc: Location) -> TyCheckResult { + fn deref_tp(&self, tp: TyParam, loc: Location) -> SingleTyCheckResult { match tp { TyParam::FreeVar(fv) if fv.is_linked() => { let inner = fv.unwrap_linked(); self.deref_tp(inner, loc) } - TyParam::FreeVar(_fv) if self.level == 0 => { - Err(TyCheckError::dummy_infer_error(fn_name!(), line!())) - } + TyParam::FreeVar(_fv) if self.level == 0 => Err(TyCheckError::dummy_infer_error( + self.cfg.input.clone(), + fn_name!(), + line!(), + )), TyParam::Type(t) => Ok(TyParam::t(self.deref_tyvar(*t, loc)?)), TyParam::App { name, mut args } => { for param in args.iter_mut() { @@ -228,13 +230,21 @@ impl Context { | TyParam::Failure if self.level == 0 => { - Err(TyCheckError::dummy_infer_error(fn_name!(), line!())) + Err(TyCheckError::dummy_infer_error( + self.cfg.input.clone(), + fn_name!(), + line!(), + )) } t => Ok(t), } } - fn deref_constraint(&self, constraint: Constraint, loc: Location) -> TyCheckResult { + fn deref_constraint( + &self, + constraint: Constraint, + loc: Location, + ) -> SingleTyCheckResult { match constraint { Constraint::Sandwiched { sub, @@ -242,7 +252,11 @@ impl Context { cyclicity: cyclic, } => { if cyclic.is_cyclic() { - return Err(TyCheckError::dummy_infer_error(fn_name!(), line!())); + return Err(TyCheckError::dummy_infer_error( + self.cfg.input.clone(), + fn_name!(), + line!(), + )); } Ok(Constraint::new_sandwiched( self.deref_tyvar(sub, loc)?, @@ -262,7 +276,7 @@ impl Context { // ?T(:> Nat, <: Sub(Str)) ==> Error! // ?T(:> {1, "a"}, <: Eq(?T(:> {1, "a"}, ...)) ==> Error! // ``` - pub(crate) fn deref_tyvar(&self, t: Type, loc: Location) -> TyCheckResult { + pub(crate) fn deref_tyvar(&self, t: Type, loc: Location) -> SingleTyCheckResult { match t { // ?T(:> Nat, <: Int)[n] ==> Nat (self.level <= n) // ?T(:> Nat, <: Sub ?U(:> {1}))[n] ==> Nat @@ -277,6 +291,7 @@ impl Context { Ok(sub_t.clone()) } else { Err(TyCheckError::subtyping_error( + self.cfg.input.clone(), line!() as usize, &self.deref_tyvar(sub_t.clone(), loc)?, &self.deref_tyvar(super_t.clone(), loc)?, @@ -294,9 +309,11 @@ impl Context { Type::FreeVar(fv) if fv.is_unbound() => { if self.level == 0 { match &*fv.crack_constraint() { - Constraint::TypeOf(_) => { - Err(TyCheckError::dummy_infer_error(fn_name!(), line!())) - } + Constraint::TypeOf(_) => Err(TyCheckError::dummy_infer_error( + self.cfg.input.clone(), + fn_name!(), + line!(), + )), _ => unreachable!(), } } else { @@ -360,15 +377,25 @@ impl Context { /// Check if all types are resolvable (if traits, check if an implementation exists) /// And replace them if resolvable - pub(crate) fn resolve(&mut self, mut hir: hir::HIR) -> TyCheckResult { + pub(crate) fn resolve( + &mut self, + mut hir: hir::HIR, + ) -> Result { self.level = 0; + let mut errs = TyCheckErrors::empty(); for chunk in hir.module.iter_mut() { - self.resolve_expr_t(chunk)?; + if let Err(err) = self.resolve_expr_t(chunk) { + errs.push(err); + } + } + if errs.is_empty() { + Ok(hir) + } else { + Err((hir, errs)) } - Ok(hir) } - fn resolve_expr_t(&self, expr: &mut hir::Expr) -> TyCheckResult<()> { + fn resolve_expr_t(&self, expr: &mut hir::Expr) -> SingleTyCheckResult<()> { match expr { hir::Expr::Lit(_) => Ok(()), hir::Expr::Accessor(acc) => { @@ -568,7 +595,11 @@ impl Context { fv.link(tp); Ok(()) } else { - Err(TyCheckError::unreachable(fn_name!(), line!())) + Err(TyCheckErrors::from(TyCheckError::unreachable( + self.cfg.input.clone(), + fn_name!(), + line!(), + ))) } } (TyParam::UnaryOp { op: lop, val: lval }, TyParam::UnaryOp { op: rop, val: rval }) @@ -591,7 +622,7 @@ impl Context { } } - fn reunify_tp(&self, before: &TyParam, after: &TyParam) -> TyCheckResult<()> { + fn reunify_tp(&self, before: &TyParam, after: &TyParam) -> SingleTyCheckResult<()> { match (before, after) { (TyParam::Value(ValueObj::Mut(l)), TyParam::Value(ValueObj::Mut(r))) => { *l.borrow_mut() = r.borrow().clone(); @@ -656,12 +687,13 @@ impl Context { self.sub_unify_tp(rhs, ge_rhs, None, false)?; self.sub_unify_tp(le_rhs, &TyParam::value(Inf), None, true) } - _ => Err(TyCheckError::pred_unification_error( + _ => Err(TyCheckErrors::from(TyCheckError::pred_unification_error( + self.cfg.input.clone(), line!() as usize, l_pred, r_pred, self.caused_by(), - )), + ))), } } (Pred::LessEqual { rhs, .. }, Pred::And(l, r)) @@ -671,12 +703,13 @@ impl Context { self.sub_unify_tp(rhs, le_rhs, None, false)?; self.sub_unify_tp(ge_rhs, &TyParam::value(NegInf), None, true) } - _ => Err(TyCheckError::pred_unification_error( + _ => Err(TyCheckErrors::from(TyCheckError::pred_unification_error( + self.cfg.input.clone(), line!() as usize, l_pred, r_pred, self.caused_by(), - )), + ))), }, (Pred::Equal { rhs, .. }, Pred::And(l, r)) | (Pred::And(l, r), Pred::Equal { rhs, .. }) => match (l.as_ref(), r.as_ref()) { @@ -685,19 +718,21 @@ impl Context { self.sub_unify_tp(rhs, le_rhs, None, false)?; self.sub_unify_tp(rhs, ge_rhs, None, false) } - _ => Err(TyCheckError::pred_unification_error( + _ => Err(TyCheckErrors::from(TyCheckError::pred_unification_error( + self.cfg.input.clone(), line!() as usize, l_pred, r_pred, self.caused_by(), - )), + ))), }, - _ => Err(TyCheckError::pred_unification_error( + _ => Err(TyCheckErrors::from(TyCheckError::pred_unification_error( + self.cfg.input.clone(), line!() as usize, l_pred, r_pred, self.caused_by(), - )), + ))), } } @@ -710,7 +745,7 @@ impl Context { after_t: &Type, bef_loc: Option, aft_loc: Option, - ) -> TyCheckResult<()> { + ) -> SingleTyCheckResult<()> { match (before_t, after_t) { (Type::FreeVar(fv), r) if fv.is_linked() => { self.reunify(&fv.crack(), r, bef_loc, aft_loc) @@ -757,6 +792,7 @@ impl Context { if ln != rn { let before_t = poly(ln.clone(), lps.clone()); return Err(TyCheckError::re_unification_error( + self.cfg.input.clone(), line!() as usize, &before_t, after_t, @@ -772,6 +808,7 @@ impl Context { } (l, r) if self.same_type_of(l, r) => Ok(()), (l, r) => Err(TyCheckError::re_unification_error( + self.cfg.input.clone(), line!() as usize, l, r, @@ -814,7 +851,8 @@ impl Context { } if !maybe_sub_is_sub { let loc = sub_loc.or(sup_loc).unwrap_or(Location::Unknown); - return Err(TyCheckError::type_mismatch_error( + return Err(TyCheckErrors::from(TyCheckError::type_mismatch_error( + self.cfg.input.clone(), line!() as usize, loc, self.caused_by(), @@ -823,7 +861,7 @@ impl Context { maybe_sub, self.get_candidates(maybe_sub), self.get_type_mismatch_hint(maybe_sup, maybe_sub), - )); + ))); } match (maybe_sub, maybe_sup) { (Type::FreeVar(lfv), _) if lfv.is_linked() => @@ -849,14 +887,15 @@ impl Context { let new_constraint = if intersec != Type::Never { Constraint::new_sandwiched(self.union(&lsub, &rsub), intersec, cyclicity) } else { - return Err(TyCheckError::subtyping_error( + return Err(TyCheckErrors::from(TyCheckError::subtyping_error( + self.cfg.input.clone(), line!() as usize, maybe_sub, maybe_sup, sub_loc, sup_loc, self.caused_by(), - )); + ))); }; if lfv.level().unwrap() <= rfv.level().unwrap() { lfv.update_constraint(new_constraint); @@ -892,14 +931,15 @@ impl Context { _ => todo!(), }; if !judge { - return Err(TyCheckError::subtyping_error( + return Err(TyCheckErrors::from(TyCheckError::subtyping_error( + self.cfg.input.clone(), line!() as usize, maybe_sub, sup, // TODO: this? sub_loc, sup_loc, self.caused_by(), - )); + ))); } if let Some(new_sub) = self.max(maybe_sub, sub) { *constraint = @@ -940,14 +980,15 @@ impl Context { // * sub_unify(?T(:> Never, <: {1}), {0}): (?T(:> Never, <: {0, 1})) Constraint::Sandwiched { sub, sup, cyclicity } => { if !self.subtype_of(sub, maybe_sup) || !self.supertype_of(sup, maybe_sup) { - return Err(TyCheckError::subtyping_error( + return Err(TyCheckErrors::from(TyCheckError::subtyping_error( + self.cfg.input.clone(), line!() as usize, sub, maybe_sup, sub_loc, sup_loc, self.caused_by(), - )); + ))); } if let Some(new_sup) = self.min(sup, maybe_sup) { *constraint = @@ -977,14 +1018,15 @@ impl Context { if let Some(r) = rrec.get(k) { self.sub_unify(l, r, sub_loc, sup_loc, param_name)?; } else { - return Err(TyCheckError::subtyping_error( + return Err(TyCheckErrors::from(TyCheckError::subtyping_error( + self.cfg.input.clone(), line!() as usize, maybe_sub, maybe_sup, sub_loc, sup_loc, self.caused_by(), - )); + ))); } } Ok(()) @@ -1015,14 +1057,15 @@ impl Context { }, ) => { if ln != rn { - return Err(TyCheckError::unification_error( + return Err(TyCheckErrors::from(TyCheckError::unification_error( + self.cfg.input.clone(), line!() as usize, maybe_sub, maybe_sup, sub_loc, sup_loc, self.caused_by(), - )); + ))); } for (l, r) in lps.iter().zip(rps.iter()) { self.sub_unify_tp(l, r, None, false)?; diff --git a/compiler/erg_compiler/effectcheck.rs b/compiler/erg_compiler/effectcheck.rs index c7893655..95878dc8 100644 --- a/compiler/erg_compiler/effectcheck.rs +++ b/compiler/erg_compiler/effectcheck.rs @@ -2,13 +2,14 @@ //! SideEffectCheckerを実装 //! 関数や不変型に副作用がないかチェックする +use erg_common::config::ErgConfig; use erg_common::log; use erg_common::traits::Stream; use erg_common::vis::Visibility; use erg_common::Str; use Visibility::*; -use crate::error::{EffectError, EffectErrors, EffectResult}; +use crate::error::{EffectError, EffectErrors}; use crate::hir::{Accessor, Array, Def, Expr, Signature, Tuple, HIR}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -27,14 +28,16 @@ use BlockKind::*; #[derive(Debug)] pub struct SideEffectChecker { + cfg: ErgConfig, path_stack: Vec<(Str, Visibility)>, block_stack: Vec, errs: EffectErrors, } impl SideEffectChecker { - pub fn new() -> Self { + pub fn new(cfg: ErgConfig) -> Self { Self { + cfg, path_stack: vec![], block_stack: vec![], errs: EffectErrors::empty(), @@ -74,7 +77,7 @@ impl SideEffectChecker { } } - pub fn check(mut self, hir: HIR) -> EffectResult { + pub fn check(mut self, hir: HIR) -> Result { self.path_stack.push((hir.name.clone(), Private)); self.block_stack.push(Module); log!(info "the side-effects checking process has started.{RESET}"); @@ -147,7 +150,7 @@ impl SideEffectChecker { if self.errs.is_empty() { Ok(hir) } else { - Err(self.errs) + Err((hir, self.errs)) } } @@ -261,6 +264,7 @@ impl SideEffectChecker { && !self.in_context_effects_allowed() { self.errs.push(EffectError::has_effect( + self.cfg.input.clone(), line!() as usize, expr, self.full_path(), @@ -317,9 +321,3 @@ impl SideEffectChecker { } } } - -impl Default for SideEffectChecker { - fn default() -> Self { - Self::new() - } -} diff --git a/compiler/erg_compiler/error.rs b/compiler/erg_compiler/error.rs index 646e3a6b..9a369a6c 100644 --- a/compiler/erg_compiler/error.rs +++ b/compiler/erg_compiler/error.rs @@ -1,5 +1,4 @@ use std::fmt::Display; -use std::ops::Add; use erg_common::astr::AtomicStr; use erg_common::color::{GREEN, RED, RESET, YELLOW}; @@ -236,35 +235,24 @@ impl CompileError { } } -#[derive(Debug)] -pub struct TyCheckError { - pub core: ErrorCore, - pub caused_by: AtomicStr, -} - -impl From for TyCheckError { - fn from(err: ParserRunnerError) -> Self { - Self { - core: err.core, - caused_by: "".into(), - } - } -} +pub type TyCheckError = CompileError; impl TyCheckError { - pub const fn new(core: ErrorCore, caused_by: AtomicStr) -> Self { - Self { core, caused_by } + pub fn dummy(input: Input, errno: usize) -> Self { + Self::new(ErrorCore::dummy(errno), input, "".into()) } - pub fn dummy(errno: usize) -> Self { - Self::new(ErrorCore::dummy(errno), "".into()) + pub fn unreachable(input: Input, fn_name: &str, line: u32) -> Self { + Self::new(ErrorCore::unreachable(fn_name, line), input, "".into()) } - pub fn unreachable(fn_name: &str, line: u32) -> Self { - Self::new(ErrorCore::unreachable(fn_name, line), "".into()) - } - - pub fn checker_bug(errno: usize, loc: Location, fn_name: &str, line: u32) -> Self { + pub fn checker_bug( + input: Input, + errno: usize, + loc: Location, + fn_name: &str, + line: u32, + ) -> Self { Self::new( ErrorCore::new( errno, @@ -278,29 +266,13 @@ impl TyCheckError { ), None, ), + input, "".into(), ) } - pub fn feature_error(errno: usize, loc: Location, name: &str, caused_by: AtomicStr) -> Self { - Self::new( - ErrorCore::new( - errno, - FeatureError, - loc, - switch_lang!( - "japanese" => format!("この機能({name})はまだ正式に提供されていません"), - "simplified_chinese" => format!("此功能({name})尚未实现"), - "traditional_chinese" => format!("此功能({name})尚未實現"), - "english" => format!("this feature({name}) is not implemented yet"), - ), - None, - ), - caused_by, - ) - } - pub fn syntax_error>( + input: Input, errno: usize, loc: Location, caused_by: AtomicStr, @@ -309,11 +281,13 @@ impl TyCheckError { ) -> Self { Self::new( ErrorCore::new(errno, SyntaxError, loc, desc, hint), + input, caused_by, ) } pub fn duplicate_decl_error( + input: Input, errno: usize, loc: Location, caused_by: AtomicStr, @@ -333,11 +307,13 @@ impl TyCheckError { ), Option::::None, ), + input, caused_by, ) } pub fn duplicate_definition_error( + input: Input, errno: usize, loc: Location, caused_by: AtomicStr, @@ -357,11 +333,13 @@ impl TyCheckError { ), Option::::None, ), + input, caused_by, ) } pub fn violate_decl_error( + input: Input, errno: usize, loc: Location, caused_by: AtomicStr, @@ -383,11 +361,13 @@ impl TyCheckError { ), Option::::None, ), + input, caused_by, ) } pub fn no_type_spec_error( + input: Input, errno: usize, loc: Location, caused_by: AtomicStr, @@ -407,11 +387,13 @@ impl TyCheckError { ), None, ), + input, caused_by, ) } pub fn no_var_error( + input: Input, errno: usize, loc: Location, caused_by: AtomicStr, @@ -442,11 +424,13 @@ impl TyCheckError { ), hint, ), + input, caused_by, ) } pub fn no_attr_error( + input: Input, errno: usize, loc: Location, caused_by: AtomicStr, @@ -477,11 +461,14 @@ impl TyCheckError { ), hint, ), + input, caused_by, ) } + #[allow(clippy::too_many_arguments)] pub fn singular_no_attr_error( + input: Input, errno: usize, loc: Location, caused_by: AtomicStr, @@ -513,11 +500,13 @@ impl TyCheckError { ), hint, ), + input, caused_by, ) } pub fn callable_impl_error<'a, C: Locational + Display>( + input: Input, errno: usize, callee: &C, param_ts: impl Iterator, @@ -541,12 +530,14 @@ impl TyCheckError { ), None, ), + input, caused_by, ) } #[allow(clippy::too_many_arguments)] pub fn type_mismatch_error( + input: Input, errno: usize, loc: Location, caused_by: AtomicStr, @@ -569,11 +560,13 @@ impl TyCheckError { ), hint, ), + input, caused_by, ) } pub fn return_type_error( + input: Input, errno: usize, loc: Location, caused_by: AtomicStr, @@ -594,11 +587,13 @@ impl TyCheckError { ), None, ), + input, caused_by, ) } pub fn uninitialized_error( + input: Input, errno: usize, loc: Location, caused_by: AtomicStr, @@ -618,11 +613,13 @@ impl TyCheckError { ), None, ), + input, caused_by, ) } pub fn argument_error( + input: Input, errno: usize, loc: Location, caused_by: AtomicStr, @@ -642,11 +639,18 @@ impl TyCheckError { ), None, ), + input, caused_by, ) } - pub fn match_error(errno: usize, loc: Location, caused_by: AtomicStr, expr_t: &Type) -> Self { + pub fn match_error( + input: Input, + errno: usize, + loc: Location, + caused_by: AtomicStr, + expr_t: &Type, + ) -> Self { Self::new( ErrorCore::new( errno, @@ -660,11 +664,18 @@ impl TyCheckError { ), None, ), + input, caused_by, ) } - pub fn infer_error(errno: usize, loc: Location, caused_by: AtomicStr, expr: &str) -> Self { + pub fn infer_error( + input: Input, + errno: usize, + loc: Location, + caused_by: AtomicStr, + expr: &str, + ) -> Self { Self::new( ErrorCore::new( errno, @@ -678,19 +689,26 @@ impl TyCheckError { ), None, ), + input, caused_by, ) } - pub fn dummy_infer_error(fn_name: &str, line: u32) -> Self { - Self::new(ErrorCore::unreachable(fn_name, line), "".into()) + pub fn dummy_infer_error(input: Input, fn_name: &str, line: u32) -> Self { + Self::new(ErrorCore::unreachable(fn_name, line), input, "".into()) } - pub fn not_relation(fn_name: &str, line: u32) -> Self { - Self::new(ErrorCore::unreachable(fn_name, line), "".into()) + pub fn not_relation(input: Input, fn_name: &str, line: u32) -> Self { + Self::new(ErrorCore::unreachable(fn_name, line), input, "".into()) } - pub fn reassign_error(errno: usize, loc: Location, caused_by: AtomicStr, name: &str) -> Self { + pub fn reassign_error( + input: Input, + errno: usize, + loc: Location, + caused_by: AtomicStr, + name: &str, + ) -> Self { let name = readable_name(name); Self::new( ErrorCore::new( @@ -705,11 +723,14 @@ impl TyCheckError { ), None, ), + input, caused_by, ) } + #[allow(clippy::too_many_arguments)] pub fn too_many_args_error( + input: Input, errno: usize, loc: Location, callee_name: &str, @@ -752,11 +773,13 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), None, ), + input, caused_by, ) } pub fn args_missing_error( + input: Input, errno: usize, loc: Location, callee_name: &str, @@ -778,11 +801,13 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), None, ), + input, caused_by, ) } pub fn multiple_args_error( + input: Input, errno: usize, loc: Location, callee_name: &str, @@ -803,11 +828,13 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), None, ), + input, caused_by, ) } pub fn unexpected_kw_arg_error( + input: Input, errno: usize, loc: Location, callee_name: &str, @@ -828,11 +855,18 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), None, ), + input, caused_by, ) } - pub fn unused_warning(errno: usize, loc: Location, name: &str, caused_by: AtomicStr) -> Self { + pub fn unused_warning( + input: Input, + errno: usize, + loc: Location, + name: &str, + caused_by: AtomicStr, + ) -> Self { let name = readable_name(name); Self::new( ErrorCore::new( @@ -847,11 +881,13 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), None, ), + input, caused_by, ) } pub fn unification_error( + input: Input, errno: usize, lhs_t: &Type, rhs_t: &Type, @@ -878,11 +914,13 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), None, ), + input, caused_by, ) } pub fn re_unification_error( + input: Input, errno: usize, lhs_t: &Type, rhs_t: &Type, @@ -909,11 +947,13 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), None, ), + input, caused_by, ) } pub fn subtyping_error( + input: Input, errno: usize, sub_t: &Type, sup_t: &Type, @@ -940,11 +980,13 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), None, ), + input, caused_by, ) } pub fn pred_unification_error( + input: Input, errno: usize, lhs: &Predicate, rhs: &Predicate, @@ -963,11 +1005,17 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), None, ), + input, caused_by, ) } - pub fn has_effect>(errno: usize, expr: &Expr, caused_by: S) -> Self { + pub fn has_effect>( + input: Input, + errno: usize, + expr: &Expr, + caused_by: S, + ) -> Self { Self::new( ErrorCore::new( errno, @@ -981,11 +1029,13 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), None, ), + input, caused_by.into(), ) } pub fn move_error>( + input: Input, errno: usize, name: &str, name_loc: Location, @@ -1017,11 +1067,13 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), None, ), + input, caused_by.into(), ) } pub fn visibility_error( + input: Input, errno: usize, loc: Location, caused_by: AtomicStr, @@ -1057,11 +1109,12 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), None, ), + input, caused_by, ) } - pub fn not_const_expr(errno: usize, loc: Location, caused_by: AtomicStr) -> Self { + pub fn not_const_expr(input: Input, errno: usize, loc: Location, caused_by: AtomicStr) -> Self { Self::new( ErrorCore::new( errno, @@ -1075,11 +1128,13 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), None, ), + input, caused_by, ) } pub fn override_error>( + input: Input, errno: usize, name: &str, name_loc: Location, @@ -1112,11 +1167,13 @@ passed keyword args: {RED}{kw_args_len}{RESET}" "english" => "cannot override by default (use `Override` decorator)", ).into()), ), + input, caused_by.into(), ) } pub fn inheritance_error( + input: Input, errno: usize, class: String, loc: Location, @@ -1135,11 +1192,13 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), None, ), + input, caused_by, ) } pub fn no_candidate_error( + input: Input, errno: usize, proj: &Type, loc: Location, @@ -1159,11 +1218,13 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), hint, ), + input, caused_by, ) } pub fn method_definition_error( + input: Input, errno: usize, loc: Location, caused_by: AtomicStr, @@ -1191,12 +1252,14 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), hint, ), + input, caused_by, ) } #[allow(clippy::too_many_arguments)] pub fn trait_member_type_error( + input: Input, errno: usize, loc: Location, caused_by: AtomicStr, @@ -1219,12 +1282,14 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), hint, ), + input, caused_by, ) } #[allow(clippy::too_many_arguments)] pub fn trait_member_not_defined_error( + input: Input, errno: usize, caused_by: AtomicStr, member_name: &str, @@ -1245,12 +1310,14 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), hint, ), + input, caused_by, ) } #[allow(clippy::too_many_arguments)] pub fn not_in_trait_error( + input: Input, errno: usize, caused_by: AtomicStr, member_name: &str, @@ -1271,11 +1338,13 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), hint, ), + input, caused_by, ) } pub fn tyvar_not_defined_error( + input: Input, errno: usize, name: &str, loc: Location, @@ -1294,21 +1363,28 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), None, ), + input, caused_by, ) } pub fn file_error( + input: Input, errno: usize, desc: String, loc: Location, caused_by: AtomicStr, hint: Option, ) -> Self { - Self::new(ErrorCore::new(errno, IoError, loc, desc, hint), caused_by) + Self::new( + ErrorCore::new(errno, IoError, loc, desc, hint), + input, + caused_by, + ) } pub fn import_error( + input: Input, errno: usize, desc: String, loc: Location, @@ -1325,10 +1401,15 @@ passed keyword args: {RED}{kw_args_len}{RESET}" (None, None) => None, }; let hint = hint.map(AtomicStr::from); - Self::file_error(errno, desc, loc, caused_by, hint) + Self::file_error(input, errno, desc, loc, caused_by, hint) } - pub fn inner_typedef_error(errno: usize, loc: Location, caused_by: AtomicStr) -> Self { + pub fn inner_typedef_error( + input: Input, + errno: usize, + loc: Location, + caused_by: AtomicStr, + ) -> Self { Self::new( ErrorCore::new( errno, @@ -1342,11 +1423,12 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), None, ), + input, caused_by, ) } - pub fn declare_error(errno: usize, loc: Location, caused_by: AtomicStr) -> Self { + pub fn declare_error(input: Input, errno: usize, loc: Location, caused_by: AtomicStr) -> Self { Self::new( ErrorCore::new( errno, @@ -1360,62 +1442,35 @@ passed keyword args: {RED}{kw_args_len}{RESET}" ), None, ), + input, caused_by, ) } } -#[derive(Debug)] -pub struct TyCheckErrors(Vec); - -impl_stream_for_wrapper!(TyCheckErrors, TyCheckError); - -impl From> for TyCheckErrors { - fn from(errs: Vec) -> Self { - Self(errs) - } -} - -impl Add for TyCheckErrors { - type Output = Self; - fn add(self, other: Self) -> Self { - Self(self.0.into_iter().chain(other.0.into_iter()).collect()) - } -} - -impl From for TyCheckErrors { - fn from(err: TyCheckError) -> Self { - Self(vec![err]) - } -} - -impl From for TyCheckErrors { - fn from(err: ParserRunnerErrors) -> Self { - Self(err.into_iter().map(TyCheckError::from).collect()) - } -} - -pub type TyCheckResult = Result; +pub type TyCheckErrors = CompileErrors; +pub type SingleTyCheckResult = Result; +pub type TyCheckResult = Result; pub type TyCheckWarning = TyCheckError; pub type TyCheckWarnings = TyCheckErrors; pub type EvalError = TyCheckError; pub type EvalErrors = TyCheckErrors; pub type EvalResult = TyCheckResult; +pub type SingleEvalResult = SingleTyCheckResult; pub type EffectError = TyCheckError; pub type EffectErrors = TyCheckErrors; -pub type EffectResult = Result; pub type OwnershipError = TyCheckError; pub type OwnershipErrors = TyCheckErrors; -pub type OwnershipResult = Result; pub type LowerError = TyCheckError; pub type LowerWarning = LowerError; pub type LowerErrors = TyCheckErrors; pub type LowerWarnings = LowerErrors; pub type LowerResult = TyCheckResult; +pub type SingleLowerResult = SingleTyCheckResult; #[derive(Debug)] pub struct CompileErrors(Vec); @@ -1448,6 +1503,7 @@ impl CompileErrors { } } -pub type CompileResult = Result; +pub type SingleCompileResult = Result; +pub type CompileResult = Result; pub type CompileWarning = CompileError; pub type CompileWarnings = CompileErrors; diff --git a/compiler/erg_compiler/lower.rs b/compiler/erg_compiler/lower.rs index d5cde8c7..2bac0d2c 100644 --- a/compiler/erg_compiler/lower.rs +++ b/compiler/erg_compiler/lower.rs @@ -26,6 +26,7 @@ use erg_type::{HasType, ParamTy, Type}; use crate::context::{ClassDefType, Context, ContextKind, RegistrationMode}; use crate::error::{ CompileError, CompileErrors, LowerError, LowerErrors, LowerResult, LowerWarnings, + SingleLowerResult, }; use crate::hir; use crate::hir::HIR; @@ -84,7 +85,9 @@ impl Runnable for ASTLowerer { fn exec(&mut self) -> Result<(), Self::Errs> { let mut ast_builder = ASTBuilder::new(self.cfg.copy()); let ast = ast_builder.build(self.input().read())?; - let (hir, warns) = self.lower(ast, "exec").map_err(|errs| self.convert(errs))?; + let (hir, warns) = self + .lower(ast, "exec") + .map_err(|(_, errs)| self.convert(errs))?; if self.cfg.verbose >= 2 { let warns = self.convert(warns); warns.fmt_all_stderr(); @@ -96,7 +99,9 @@ impl Runnable for ASTLowerer { fn eval(&mut self, src: String) -> Result { let mut ast_builder = ASTBuilder::new(self.cfg.copy()); let ast = ast_builder.build(src)?; - let (hir, ..) = self.lower(ast, "eval").map_err(|errs| self.convert(errs))?; + let (hir, ..) = self + .lower(ast, "eval") + .map_err(|(_, errs)| self.convert(errs))?; Ok(format!("{hir}")) } } @@ -109,8 +114,8 @@ impl ASTLowerer { py_mod_cache: SharedModuleCache, ) -> Self { Self { + ctx: Context::new_module(mod_name, cfg.clone(), mod_cache, py_mod_cache), cfg, - ctx: Context::new_module(mod_name, mod_cache, py_mod_cache), errs: LowerErrors::empty(), warns: LowerWarnings::empty(), } @@ -129,11 +134,12 @@ impl ASTLowerer { name: &Str, expect: &Type, found: &Type, - ) -> LowerResult<()> { + ) -> SingleLowerResult<()> { self.ctx .sub_unify(found, expect, None, Some(loc), Some(name)) .map_err(|_| { LowerError::type_mismatch_error( + self.cfg.input.clone(), line!() as usize, loc, self.ctx.caused_by(), @@ -150,9 +156,10 @@ impl ASTLowerer { /// OK: exec `i: Int = 1` /// NG: exec `1 + 2` /// OK: exec `None` - fn use_check(&self, expr: &hir::Expr, mode: &str) -> LowerResult<()> { + fn use_check(&self, expr: &hir::Expr, mode: &str) -> SingleLowerResult<()> { if mode != "eval" && !expr.ref_t().is_nonelike() && !expr.is_type_asc() { Err(LowerError::syntax_error( + self.cfg.input.clone(), 0, expr.loc(), AtomicStr::arc(&self.ctx.name[..]), @@ -203,7 +210,8 @@ impl ASTLowerer { let elem = self.lower_expr(elem.expr)?; union = self.ctx.union(&union, elem.ref_t()); if matches!(union, Type::Or(_, _)) { - return Err(LowerError::syntax_error( + return Err(LowerErrors::from(LowerError::syntax_error( + self.cfg.input.clone(), line!() as usize, elem.loc(), AtomicStr::arc(&self.ctx.name[..]), @@ -222,7 +230,7 @@ impl ASTLowerer { ) .into(), ), - )); + ))); } new_array.push(elem); } @@ -547,11 +555,12 @@ impl ASTLowerer { log!(info "entered {}({})", fn_name!(), def.sig); if def.def_kind().is_class_or_trait() && self.ctx.kind != ContextKind::Module { self.ctx.decls.remove(def.sig.ident().unwrap().inspect()); - return Err(LowerError::inner_typedef_error( + return Err(LowerErrors::from(LowerError::inner_typedef_error( + self.cfg.input.clone(), line!() as usize, def.loc(), self.ctx.caused_by(), - )); + ))); } let name = if let Some(name) = def.sig.name_as_str() { name.clone() @@ -563,12 +572,13 @@ impl ASTLowerer { .registered_info(&name, def.sig.is_const()) .is_some() { - return Err(LowerError::reassign_error( + return Err(LowerErrors::from(LowerError::reassign_error( + self.cfg.input.clone(), line!() as usize, def.sig.loc(), self.ctx.caused_by(), &name, - )); + ))); } let kind = ContextKind::from(def.def_kind()); self.ctx.grow(&name, kind, def.sig.vis())?; @@ -623,13 +633,13 @@ impl ASTLowerer { match block.first().unwrap() { hir::Expr::Call(call) => { if let Some(kind) = call.import_kind() { - let current_input = self.input().clone(); - self.ctx.outer.as_mut().unwrap().import_mod( + if let Err(errs) = self.ctx.outer.as_mut().unwrap().import_mod( kind, - current_input, &ident.name, &call.args.pos_args.first().unwrap().expr, - )?; + ) { + self.errs.extend(errs.into_iter()); + }; } } _other => {} @@ -723,22 +733,24 @@ impl ASTLowerer { }; if let Some((_, class_root)) = self.ctx.get_nominal_type_ctx(&class) { if !class_root.kind.is_class() { - return Err(LowerError::method_definition_error( + return Err(LowerErrors::from(LowerError::method_definition_error( + self.cfg.input.clone(), line!() as usize, methods.loc(), self.ctx.caused_by(), &class.name(), None, - )); + ))); } } else { - return Err(LowerError::no_var_error( + return Err(LowerErrors::from(LowerError::no_var_error( + self.cfg.input.clone(), line!() as usize, methods.class.loc(), self.ctx.caused_by(), &class.name(), self.ctx.get_similar_name(&class.name()), - )); + ))); } self.ctx .grow(&class.name(), ContextKind::MethodDefs, Private)?; @@ -780,7 +792,7 @@ impl ASTLowerer { .args .get_left_or_key("Super") .unwrap(); - Self::check_inheritable(&mut self.errs, type_obj, sup_type, &hir_def.sig); + Self::check_inheritable(&self.cfg, &mut self.errs, type_obj, sup_type, &hir_def.sig); // vi.t.non_default_params().unwrap()[0].typ().clone() let (__new__, need_to_gen_new) = if let (Some(dunder_new_vi), Some(new_vi)) = ( ctx.get_current_scope_var("__new__"), @@ -803,6 +815,7 @@ impl ASTLowerer { /// HACK: Cannot be methodized this because `&self` has been taken immediately before. fn check_inheritable( + cfg: &ErgConfig, errs: &mut LowerErrors, type_obj: &GenTypeObj, sup_class: &hir::Expr, @@ -812,6 +825,7 @@ impl ASTLowerer { if let Some(impls) = gen.impls.as_ref() { if !impls.contains_intersec(&builtin_mono("InheritableType")) { errs.push(LowerError::inheritance_error( + cfg.input.clone(), line!() as usize, sup_class.to_string(), sup_class.loc(), @@ -820,6 +834,7 @@ impl ASTLowerer { } } else { errs.push(LowerError::inheritance_error( + cfg.input.clone(), line!() as usize, sup_class.to_string(), sup_class.loc(), @@ -841,6 +856,7 @@ impl ASTLowerer { } } self.errs.push(LowerError::override_error( + self.cfg.input.clone(), line!() as usize, method_name.inspect(), method_name.loc(), @@ -858,7 +874,7 @@ impl ASTLowerer { impl_trait: Option<(Type, Location)>, class: &Type, methods: &Context, - ) -> LowerResult<()> { + ) -> SingleLowerResult<()> { if let Some((impl_trait, loc)) = impl_trait { // assume the class has implemented the trait, regardless of whether the implementation is correct let trait_ctx = self @@ -881,6 +897,7 @@ impl ASTLowerer { unverified_names.remove(name); if !self.ctx.supertype_of(typ, &vi.t) { self.errs.push(LowerError::trait_member_type_error( + self.cfg.input.clone(), line!() as usize, name.loc(), self.ctx.caused_by(), @@ -893,6 +910,7 @@ impl ASTLowerer { } } else { self.errs.push(LowerError::trait_member_not_defined_error( + self.cfg.input.clone(), line!() as usize, self.ctx.caused_by(), &field.symbol, @@ -904,6 +922,7 @@ impl ASTLowerer { } for unverified in unverified_names { self.errs.push(LowerError::trait_member_not_defined_error( + self.cfg.input.clone(), line!() as usize, self.ctx.caused_by(), unverified.inspect(), @@ -919,6 +938,7 @@ impl ASTLowerer { } } else { return Err(LowerError::type_mismatch_error( + self.cfg.input.clone(), line!() as usize, loc, self.ctx.caused_by(), @@ -931,6 +951,7 @@ impl ASTLowerer { } } else { return Err(LowerError::no_var_error( + self.cfg.input.clone(), line!() as usize, loc, self.ctx.caused_by(), @@ -953,6 +974,7 @@ impl ASTLowerer { { if already_defined_vi.kind != VarKind::Auto { self.errs.push(LowerError::duplicate_definition_error( + self.cfg.input.clone(), line!() as usize, newly_defined_name.loc(), methods.name.clone().into(), @@ -1044,11 +1066,12 @@ impl ASTLowerer { ) -> LowerResult { log!(info "entered {}({sig})", fn_name!()); if body.block.len() > 1 { - return Err(LowerError::declare_error( + return Err(LowerErrors::from(LowerError::declare_error( + self.cfg.input.clone(), line!() as usize, body.block.loc(), self.ctx.caused_by(), - )); + ))); } let block = hir::Block::new(vec![self.declare_chunk(body.block.remove(0))?]); let found_body_t = block.ref_t(); @@ -1076,12 +1099,13 @@ impl ASTLowerer { .registered_info(&name, def.sig.is_const()) .is_some() { - return Err(LowerError::reassign_error( + return Err(LowerErrors::from(LowerError::reassign_error( + self.cfg.input.clone(), line!() as usize, def.sig.loc(), self.ctx.caused_by(), &name, - )); + ))); } let res = match def.sig { ast::Signature::Subr(_sig) => todo!(), @@ -1112,11 +1136,12 @@ impl ASTLowerer { tasc.t_spec, )) } - other => Err(LowerError::declare_error( + other => Err(LowerErrors::from(LowerError::declare_error( + self.cfg.input.clone(), line!() as usize, other.loc(), self.ctx.caused_by(), - )), + ))), } } @@ -1124,18 +1149,19 @@ impl ASTLowerer { log!(info "entered {}", fn_name!()); match expr { ast::Expr::Def(def) => Ok(hir::Expr::Def(self.declare_alias(def)?)), - ast::Expr::ClassDef(defs) => Err(LowerError::feature_error( - line!() as usize, + ast::Expr::ClassDef(defs) => Err(LowerErrors::from(LowerError::feature_error( + self.cfg.input.clone(), defs.loc(), "class declaration", self.ctx.caused_by(), - )), + ))), ast::Expr::TypeAsc(tasc) => Ok(hir::Expr::TypeAsc(self.declare_type(tasc)?)), - other => Err(LowerError::declare_error( + other => Err(LowerErrors::from(LowerError::declare_error( + self.cfg.input.clone(), line!() as usize, other.loc(), self.ctx.caused_by(), - )), + ))), } } @@ -1146,18 +1172,24 @@ impl ASTLowerer { Ok(chunk) => { module.push(chunk); } - Err(e) => { - self.errs.push(e); + Err(errs) => { + self.errs.extend(errs.into_iter()); } } } HIR::new(ast.name, module) } - pub fn lower(&mut self, ast: AST, mode: &str) -> Result<(HIR, LowerWarnings), LowerErrors> { + pub fn lower( + &mut self, + ast: AST, + mode: &str, + ) -> Result<(HIR, LowerWarnings), (Option, LowerErrors)> { log!(info "the AST lowering process has started."); log!(info "the type-checking process has started."); - let ast = Reorderer::new().reorder(ast)?; + let ast = Reorderer::new(self.cfg.clone()) + .reorder(ast) + .map_err(|errs| (None, errs))?; if mode == "declare" { let hir = self.declare_module(ast); if self.errs.is_empty() { @@ -1166,18 +1198,20 @@ impl ASTLowerer { return Ok((hir, LowerWarnings::from(self.warns.take_all()))); } else { log!(err "the declaring process has failed."); - return Err(LowerErrors::from(self.errs.take_all())); + return Err((Some(hir), LowerErrors::from(self.errs.take_all()))); } } let mut module = hir::Module::with_capacity(ast.module.len()); - self.ctx.preregister(ast.module.block())?; + if let Err(errs) = self.ctx.preregister(ast.module.block()) { + self.errs.extend(errs.into_iter()); + } for chunk in ast.module.into_iter() { match self.lower_expr(chunk) { Ok(chunk) => { module.push(chunk); } - Err(e) => { - self.errs.push(e); + Err(errs) => { + self.errs.extend(errs.into_iter()); } } } @@ -1188,16 +1222,16 @@ impl ASTLowerer { log!(info "HIR (not resolved, current errs: {}):\n{hir}", self.errs.len()); let hir = match self.ctx.resolve(hir) { Ok(hir) => hir, - Err(err) => { - self.errs.push(err); + Err((hir, errs)) => { + self.errs.extend(errs.into_iter()); log!(err "the AST lowering process has failed."); - return Err(LowerErrors::from(self.errs.take_all())); + return Err((Some(hir), LowerErrors::from(self.errs.take_all()))); } }; // TODO: recursive check for chunk in hir.module.iter() { - if let Err(e) = self.use_check(chunk, mode) { - self.errs.push(e); + if let Err(err) = self.use_check(chunk, mode) { + self.errs.push(err); } } if self.errs.is_empty() { @@ -1206,7 +1240,7 @@ impl ASTLowerer { Ok((hir, LowerWarnings::from(self.warns.take_all()))) } else { log!(err "the AST lowering process has failed."); - Err(LowerErrors::from(self.errs.take_all())) + Err((Some(hir), LowerErrors::from(self.errs.take_all()))) } } } diff --git a/compiler/erg_compiler/ownercheck.rs b/compiler/erg_compiler/ownercheck.rs index 6e516a32..d36944b5 100644 --- a/compiler/erg_compiler/ownercheck.rs +++ b/compiler/erg_compiler/ownercheck.rs @@ -1,5 +1,6 @@ use std::mem; +use erg_common::config::ErgConfig; use erg_common::dict::Dict; use erg_common::error::Location; use erg_common::log; @@ -11,7 +12,7 @@ use Visibility::*; use erg_type::{HasType, Ownership}; -use crate::error::{OwnershipError, OwnershipErrors, OwnershipResult}; +use crate::error::{OwnershipError, OwnershipErrors}; use crate::hir::{self, Accessor, Array, Block, Def, Expr, Identifier, Signature, Tuple, HIR}; #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] @@ -29,14 +30,16 @@ struct LocalVars { #[derive(Debug)] pub struct OwnershipChecker { + cfg: ErgConfig, path_stack: Vec<(Str, Visibility)>, dict: Dict, errs: OwnershipErrors, } impl OwnershipChecker { - pub fn new() -> Self { + pub fn new(cfg: ErgConfig) -> Self { OwnershipChecker { + cfg, path_stack: vec![], dict: Dict::new(), errs: OwnershipErrors::empty(), @@ -57,7 +60,7 @@ impl OwnershipChecker { // moveされた後の変数が使用されていないかチェックする // ProceduralでないメソッドでRefMutが使われているかはSideEffectCheckerでチェックする - pub fn check(&mut self, hir: HIR) -> OwnershipResult { + pub fn check(&mut self, hir: HIR) -> Result { log!(info "the ownership checking process has started.{RESET}"); if self.full_path() != ("::".to_string() + &hir.name[..]) { self.path_stack.push((hir.name.clone(), Private)); @@ -74,7 +77,7 @@ impl OwnershipChecker { if self.errs.is_empty() { Ok(hir) } else { - Err(mem::take(&mut self.errs)) + Err((hir, mem::take(&mut self.errs))) } } @@ -272,6 +275,7 @@ impl OwnershipChecker { if let Some(moved_loc) = self.nth_outer_scope(n).dropped_vars.get(name) { let moved_loc = *moved_loc; return Err(OwnershipError::move_error( + self.cfg.input.clone(), line!() as usize, name, loc, @@ -286,6 +290,6 @@ impl OwnershipChecker { impl Default for OwnershipChecker { fn default() -> Self { - Self::new() + Self::new(ErgConfig::default()) } } diff --git a/compiler/erg_compiler/reorder.rs b/compiler/erg_compiler/reorder.rs index c57c6df4..4e21f1b3 100644 --- a/compiler/erg_compiler/reorder.rs +++ b/compiler/erg_compiler/reorder.rs @@ -1,3 +1,4 @@ +use erg_common::config::ErgConfig; use erg_common::dict::Dict; use erg_common::log; use erg_common::traits::{Locational, Stream}; @@ -10,6 +11,7 @@ use crate::error::{TyCheckError, TyCheckErrors}; /// Combine method definitions across multiple modules, specialized class contexts, etc. #[derive(Debug, Default)] pub struct Reorderer { + cfg: ErgConfig, // TODO: inner scope types pub def_root_pos_map: Dict, pub deps: Dict>, @@ -17,8 +19,9 @@ pub struct Reorderer { } impl Reorderer { - pub fn new() -> Self { + pub fn new(cfg: ErgConfig) -> Self { Self { + cfg, def_root_pos_map: Dict::new(), deps: Dict::new(), errs: TyCheckErrors::empty(), @@ -67,6 +70,7 @@ impl Reorderer { .keys() .fold("".to_string(), |acc, key| acc + &key[..] + ","); self.errs.push(TyCheckError::no_var_error( + self.cfg.input.clone(), line!() as usize, methods.class.loc(), "".into(), @@ -105,6 +109,7 @@ impl Reorderer { .keys() .fold("".to_string(), |acc, key| acc + &key[..] + ","); self.errs.push(TyCheckError::no_var_error( + self.cfg.input.clone(), line!() as usize, methods.class.loc(), "".into(), diff --git a/compiler/erg_compiler/tests/test.rs b/compiler/erg_compiler/tests/test.rs index d03f0f44..1b67ed57 100644 --- a/compiler/erg_compiler/tests/test.rs +++ b/compiler/erg_compiler/tests/test.rs @@ -1,3 +1,4 @@ +use erg_common::config::ErgConfig; use erg_compiler::context::Context; use erg_compiler::mod_cache::SharedModuleCache; @@ -5,6 +6,7 @@ use erg_compiler::mod_cache::SharedModuleCache; fn test_subtyping() -> Result<(), ()> { let context = Context::new_module( "", + ErgConfig::default(), SharedModuleCache::new(), SharedModuleCache::new(), ); @@ -16,6 +18,7 @@ fn test_subtyping() -> Result<(), ()> { fn test_instantiation_and_generalization() -> Result<(), ()> { let context = Context::new_module( "", + ErgConfig::default(), SharedModuleCache::new(), SharedModuleCache::new(), ); @@ -43,6 +46,7 @@ fn test_resolve_trait_inner1() -> Result<(), ()> { fn test_dir() -> Result<(), ()> { let context = Context::new_module( "", + ErgConfig::default(), SharedModuleCache::new(), SharedModuleCache::new(), ); diff --git a/compiler/erg_parser/tests/parse_test.rs b/compiler/erg_parser/tests/parse_test.rs index 721c3366..76bc8a76 100644 --- a/compiler/erg_parser/tests/parse_test.rs +++ b/compiler/erg_parser/tests/parse_test.rs @@ -49,17 +49,9 @@ fn parse_test2_advanced_syntax() -> Result<(), ParserRunnerErrors> { fn parse_test_from_code(file_path: &'static str) -> Result<(), ParserRunnerErrors> { let input = Input::File(file_path.into()); let cfg = ErgConfig { - mode: "exec", - opt_level: 1, - dump_as_pyc: false, - python_ver: None, - py_server_timeout: 100, - quiet_startup: false, input: input.clone(), - module: "", - verbose: 2, - ps1: ">>> ", - ps2: "... ", + py_server_timeout: 100, + ..ErgConfig::default() }; let lexer = Lexer::new(input.clone()); let mut parser = ParserRunner::new(cfg); diff --git a/examples/a11y.er b/examples/a11y.er index fab21c81..051bfcc0 100644 --- a/examples/a11y.er +++ b/examples/a11y.er @@ -1,6 +1,8 @@ private = "this is a private variable" .public = "this is a public variable" +1 + .C = Class {.x = Int} .C. x = 1