From 800b6c43d96b819714dbed9746e3b143e67e4328 Mon Sep 17 00:00:00 2001 From: Shunsuke Shibayama Date: Thu, 15 Dec 2022 15:18:25 +0900 Subject: [PATCH] Eliminate `todo!`s --- compiler/erg_compiler/context/eval.rs | 90 +++++++---- .../context/initialize/const_func.rs | 12 +- compiler/erg_compiler/context/inquire.rs | 6 +- compiler/erg_compiler/context/instantiate.rs | 30 ++-- compiler/erg_compiler/context/tyvar.rs | 153 ++++++++++++------ compiler/erg_compiler/error.rs | 45 ++++++ compiler/erg_compiler/lower.rs | 61 ++++--- compiler/erg_compiler/ty/value.rs | 15 +- 8 files changed, 282 insertions(+), 130 deletions(-) diff --git a/compiler/erg_compiler/context/eval.rs b/compiler/erg_compiler/context/eval.rs index b363c48d..c2c0f25e 100644 --- a/compiler/erg_compiler/context/eval.rs +++ b/compiler/erg_compiler/context/eval.rs @@ -1,7 +1,6 @@ use std::mem; use erg_common::dict::Dict; -use erg_common::enum_unwrap; use erg_common::error::Location; #[allow(unused)] use erg_common::log; @@ -10,6 +9,7 @@ use erg_common::shared::Shared; use erg_common::traits::{Locational, Stream}; use erg_common::vis::Field; use erg_common::{dict, fn_name, option_enum_unwrap, set}; +use erg_common::{enum_unwrap, fmt_vec}; use erg_common::{RcArray, Str}; use OpKind::*; @@ -34,6 +34,17 @@ use crate::error::{EvalError, EvalErrors, EvalResult, SingleEvalResult}; use super::instantiate::TyVarCache; use super::Variance; +macro_rules! feature_error { + ($ctx: expr, $loc: expr, $name: expr) => { + $crate::feature_error!(EvalErrors, EvalError, $ctx, $loc, $name) + }; +} +macro_rules! unreachable_error { + ($ctx: expr) => { + $crate::unreachable_error!(EvalErrors, EvalError, $ctx) + }; +} + #[inline] pub fn type_from_token_kind(kind: TokenKind) -> Type { use TokenKind::*; @@ -139,7 +150,9 @@ impl Context { let obj = self.eval_const_expr(&attr.obj)?; Ok(self.eval_attr(obj, &attr.ident)?) } - _ => todo!(), + other => { + feature_error!(self, other.loc(), &format!("eval {other}")).map_err(Into::into) + } } } @@ -260,7 +273,9 @@ impl Context { fn call(&self, subr: ConstSubr, args: ValueArgs, loc: Location) -> EvalResult { match subr { - ConstSubr::User(_user) => todo!(), + ConstSubr::User(_user) => { + feature_error!(self, loc, "calling user-defined subroutines").map_err(Into::into) + } ConstSubr::Builtin(builtin) => builtin.call(args, self).map_err(|mut e| { if e.0.loc.is_unknown() { e.0.loc = loc; @@ -387,7 +402,7 @@ impl Context { fn eval_const_record(&self, record: &Record) -> EvalResult { match record { Record::Normal(rec) => self.eval_const_normal_record(rec), - Record::Mixed(_rec) => unreachable!(), // should be desugared + Record::Mixed(_rec) => unreachable_error!(self), // should be desugared } } @@ -408,9 +423,13 @@ impl Context { let ident = match &attr.sig { Signature::Var(var) => match &var.pat { VarPattern::Ident(ident) => Field::new(ident.vis(), ident.inspect().clone()), - _ => todo!(), + other => { + return feature_error!(self, other.loc(), &format!("record field: {other}")) + } }, - _ => todo!(), + other => { + return feature_error!(self, other.loc(), &format!("record field: {other}")) + } }; attrs.push((ident, elem)); } @@ -720,7 +739,8 @@ impl Context { (lhs @ TyParam::FreeVar(_), rhs) => Ok(TyParam::bin(op, lhs, rhs)), (lhs, rhs @ TyParam::FreeVar(_)) => Ok(TyParam::bin(op, lhs, rhs)), (e @ TyParam::Erased(_), _) | (_, e @ TyParam::Erased(_)) => Ok(e), - (l, r) => todo!("{l:?} {op} {r:?}"), + (l, r) => feature_error!(self, Location::Unknown, &format!("{l:?} {op} {r:?}")) + .map_err(Into::into), } } @@ -742,7 +762,7 @@ impl Context { line!(), ))), Mutate => Ok(ValueObj::Mut(Shared::new(val))), - other => unreachable!("{other}"), + _other => unreachable_error!(self), } } @@ -759,15 +779,19 @@ impl Context { let tp = TyParam::FreeVar(fv); Ok(tp) } else { - todo!("{op} {fv}") + feature_error!(self, Location::Unknown, &format!("{op} {fv}")) } } - other => todo!("{op} {other}"), + other => feature_error!(self, Location::Unknown, &format!("{op} {other}")), } } - fn eval_app(&self, _name: Str, _args: Vec) -> EvalResult { - todo!() + fn eval_app(&self, name: Str, args: Vec) -> EvalResult { + feature_error!( + self, + Location::Unknown, + &format!("{name}({})", fmt_vec(&args)) + ) } /// 量化変数などはそのまま返す @@ -810,12 +834,7 @@ impl Context { Ok(TyParam::Dict(new_dic)) } TyParam::Type(_) | TyParam::Erased(_) | TyParam::Value(_) => Ok(p.clone()), - _other => Err(EvalErrors::from(EvalError::feature_error( - self.cfg.input.clone(), - Location::Unknown, - "???", - self.caused_by(), - ))), + _other => feature_error!(self, Location::Unknown, "???"), } } @@ -897,12 +916,7 @@ impl Context { Ok(not(l, r)) } other if other.is_monomorphic() => Ok(other), - _other => Err(EvalErrors::from(EvalError::feature_error( - self.cfg.input.clone(), - t_loc, - "???", - self.caused_by(), - ))), + _other => feature_error!(self, t_loc, "???"), } } @@ -1252,7 +1266,7 @@ impl Context { let t = enum_unwrap!(t, ValueObj::Type); // TODO: error handling return Ok(t.into_typ()); } else { - todo!() + return feature_error!(self, t_loc, "??"); } } for (_class, methods) in ty_ctx.methods_list.iter() { @@ -1267,7 +1281,7 @@ impl Context { let t = enum_unwrap!(t, ValueObj::Type); // TODO: error handling return Ok(t.into_typ()); } else { - todo!() + return feature_error!(self, t_loc, "??"); } } } @@ -1332,7 +1346,7 @@ impl Context { if let Some(t) = fv.get_type() { Ok(t) } else { - todo!() // Type + feature_error!(self, Location::Unknown, "??") } } TyParam::Type(typ) => Ok(self.meta_type(&typ)), @@ -1361,13 +1375,21 @@ impl Context { dict @ TyParam::Dict(_) => Ok(dict_t(dict)), TyParam::UnaryOp { op, val } => match op { OpKind::Mutate => Ok(self.get_tp_t(&val)?.mutate()), - _ => todo!(), + _ => feature_error!(self, Location::Unknown, "??"), }, TyParam::BinOp { op, lhs, rhs } => { let op_name = op_to_name(op); - todo!("get type: {op_name}({lhs}, {rhs})") + feature_error!( + self, + Location::Unknown, + &format!("get type: {op_name}({lhs}, {rhs})") + ) } - other => todo!("{other}"), + other => feature_error!( + self, + Location::Unknown, + &format!("getting the type of {other}") + ), } } @@ -1380,7 +1402,7 @@ impl Context { if let Some(t) = fv.get_type() { Ok(t) } else { - todo!() + feature_error!(self, Location::Unknown, "??") } } TyParam::Type(_) => Ok(Type::Type), @@ -1395,7 +1417,11 @@ impl Context { )) }) } - other => todo!("{other}"), + other => feature_error!( + self, + Location::Unknown, + &format!("getting the class of {other}") + ), } } diff --git a/compiler/erg_compiler/context/initialize/const_func.rs b/compiler/erg_compiler/context/initialize/const_func.rs index 15b62206..2d2ed8ef 100644 --- a/compiler/erg_compiler/context/initialize/const_func.rs +++ b/compiler/erg_compiler/context/initialize/const_func.rs @@ -3,8 +3,9 @@ use std::mem; use erg_common::enum_unwrap; use crate::context::Context; +use crate::feature_error; use crate::ty::constructors::{and, mono}; -use crate::ty::value::{EvalValueResult, GenTypeObj, TypeObj, ValueObj}; +use crate::ty::value::{EvalValueError, EvalValueResult, GenTypeObj, TypeObj, ValueObj}; use crate::ty::ValueArgs; use erg_common::error::{ErrorCore, ErrorKind, Location, SubMessage}; use erg_common::style::{Color, StyledStr, StyledString, THEME}; @@ -110,7 +111,12 @@ pub fn inheritable_func(mut args: ValueArgs, _ctx: &Context) -> EvalValueResult< } Ok(ValueObj::Type(TypeObj::Generated(gen))) } - _ => todo!(), + other => feature_error!( + EvalValueError, + _ctx, + Location::Unknown, + &format!("Inheritable {other}") + ), } } @@ -126,7 +132,7 @@ pub fn trait_func(mut args: ValueArgs, ctx: &Context) -> EvalValueResult { - if let Some(_attr_name) = attr_name { - todo!() + if let Some(attr_name) = attr_name { + feature_error!(TyCheckErrors, TyCheckError, self, attr_name.loc(), "") } else { let is_procedural = obj .show_acc() diff --git a/compiler/erg_compiler/context/instantiate.rs b/compiler/erg_compiler/context/instantiate.rs index 2889e914..a3e86c67 100644 --- a/compiler/erg_compiler/context/instantiate.rs +++ b/compiler/erg_compiler/context/instantiate.rs @@ -19,12 +19,14 @@ use erg_parser::ast; use erg_parser::token::TokenKind; use erg_parser::Parser; +use crate::feature_error; use crate::ty::constructors::*; use crate::ty::free::CanbeFree; use crate::ty::free::{Constraint, HasLevel}; use crate::ty::typaram::{IntervalOp, TyParam, TyParamOrdering}; use crate::ty::value::ValueObj; use crate::ty::{HasType, ParamTy, Predicate, SubrKind, Type}; +use crate::type_feature_error; use TyParamOrdering::*; use Type::*; @@ -393,7 +395,7 @@ impl Context { ))) } } - other => todo!("{other}"), + other => type_feature_error!(self, other.loc(), &format!("instantiating {other}")), } } @@ -579,7 +581,7 @@ impl Context { self.get_similar_name(name.inspect()), ))) } - _ => todo!(), + other => type_feature_error!(self, other.loc(), &format!("instantiating {other}")), } } @@ -592,7 +594,7 @@ impl Context { match self.instantiate_const_expr(expr, erased_idx, tmp_tv_cache)? { TyParam::Type(t) => Ok(*t), TyParam::Value(ValueObj::Type(t)) => Ok(t.into_typ()), - other => todo!("{other}"), + other => type_feature_error!(self, expr.loc(), &format!("{other}")), } } @@ -621,13 +623,13 @@ impl Context { pub(crate) fn instantiate_typespec( &self, - spec: &TypeSpec, + t_spec: &TypeSpec, opt_decl_t: Option<&ParamTy>, tmp_tv_cache: &mut TyVarCache, mode: RegistrationMode, not_found_is_qvar: bool, ) -> TyCheckResult { - match spec { + match t_spec { TypeSpec::Infer(_) => Ok(free_var(self.level, Constraint::new_type_of(Type))), TypeSpec::PreDeclTy(predecl) => Ok(self.instantiate_predecl_t( predecl, @@ -830,7 +832,7 @@ impl Context { )) } TypeSpec::TypeApp { spec, args } => { - todo!("{spec}{args}") + type_feature_error!(self, t_spec.loc(), &format!("instantiating {spec}{args}")) } } } @@ -850,7 +852,9 @@ impl Context { TokenKind::SubtypeOf => Constraint::new_subtype_of( self.instantiate_typespec(&spec.t_spec, None, tv_cache, mode, true)?, ), - TokenKind::SupertypeOf => todo!(), + TokenKind::SupertypeOf => { + return type_feature_error!(self, spec.loc(), "supertype of"); + } TokenKind::Colon => Constraint::new_type_of(self.instantiate_typespec( &spec.t_spec, None, @@ -862,10 +866,14 @@ impl Context { }; let tv = named_free_var(lhs.inspect().clone(), self.level, constr); tv_cache.push_or_init_tyvar(lhs.inspect(), &tv); + Ok(()) } - TypeBoundSpec::WithDefault { .. } => todo!(), + TypeBoundSpec::WithDefault { .. } => type_feature_error!( + self, + bound.loc(), + "type boundary specification with default" + ), } - Ok(()) } pub(crate) fn instantiate_ty_bounds( @@ -983,7 +991,7 @@ impl Context { | TyParam::Mono(_) | TyParam::FreeVar(_) | TyParam::Erased(_)) => Ok(p), - other => todo!("{other}"), + other => type_feature_error!(self, loc, &format!("instantiating {other}")), } } @@ -1134,7 +1142,7 @@ impl Context { Ok(not(l, r)) } other if other.is_monomorphic() => Ok(other), - other => todo!("{other}"), + other => type_feature_error!(self, loc, &format!("instantiating {other}")), } } diff --git a/compiler/erg_compiler/context/tyvar.rs b/compiler/erg_compiler/context/tyvar.rs index 6c6d4b86..c1371285 100644 --- a/compiler/erg_compiler/context/tyvar.rs +++ b/compiler/erg_compiler/context/tyvar.rs @@ -18,7 +18,7 @@ use crate::ty::{HasType, Predicate, Type}; // use crate::context::eval::SubstContext; use crate::context::{Context, Variance}; use crate::error::{SingleTyCheckResult, TyCheckError, TyCheckErrors, TyCheckResult}; -use crate::hir; +use crate::{feature_error, hir, type_feature_error}; use Predicate as Pred; use Type::*; @@ -674,7 +674,12 @@ impl Context { self.resolve_expr_t(&mut arr.len)?; Ok(()) } - _ => todo!(), + other => feature_error!( + TyCheckError, + self, + other.loc(), + "resolve types of array comprehension" + ), }, hir::Expr::Tuple(tuple) => match tuple { hir::Tuple::Normal(tup) => { @@ -711,7 +716,12 @@ impl Context { } Ok(()) } - other => todo!("{other}"), + other => feature_error!( + TyCheckError, + self, + other.loc(), + "resolve types of dict comprehension" + ), }, hir::Expr::Record(record) => { for attr in record.attrs.iter_mut() { @@ -1367,10 +1377,12 @@ impl Context { } Ok(()) } - (Type::FreeVar(lfv), _) if lfv.is_linked() => - self.sub_unify(&lfv.crack(), maybe_sup, loc, param_name), - (_, Type::FreeVar(rfv)) if rfv.is_linked() => - self.sub_unify(maybe_sub, &rfv.crack(), loc, param_name), + (Type::FreeVar(lfv), _) if lfv.is_linked() => { + self.sub_unify(&lfv.crack(), maybe_sup, loc, param_name) + } + (_, Type::FreeVar(rfv)) if rfv.is_linked() => { + self.sub_unify(maybe_sub, &rfv.crack(), loc, param_name) + } (_, Type::FreeVar(rfv)) if rfv.is_unbound() => { // NOTE: cannot `borrow_mut` because of cycle reference let rfv_ref = unsafe { rfv.as_ptr().as_mut().unwrap() }; @@ -1477,15 +1489,24 @@ impl Context { } (Type::Subr(lsub), Type::Subr(rsub)) => { for lpt in lsub.default_params.iter() { - if let Some(rpt) = rsub.default_params.iter().find(|rpt| rpt.name() == lpt.name()) { + if let Some(rpt) = rsub + .default_params + .iter() + .find(|rpt| rpt.name() == lpt.name()) + { // contravariant self.sub_unify(rpt.typ(), lpt.typ(), loc, param_name)?; - } else { todo!() } + } else { + todo!() + } } - lsub.non_default_params.iter().zip(rsub.non_default_params.iter()).try_for_each(|(l, r)| { - // contravariant - self.sub_unify(r.typ(), l.typ(), loc, param_name) - })?; + lsub.non_default_params + .iter() + .zip(rsub.non_default_params.iter()) + .try_for_each(|(l, r)| { + // contravariant + self.sub_unify(r.typ(), l.typ(), loc, param_name) + })?; // covariant self.sub_unify(&lsub.return_t, &rsub.return_t, loc, param_name)?; Ok(()) @@ -1493,17 +1514,32 @@ impl Context { (Type::Quantified(lsub), Type::Subr(rsub)) => { let Type::Subr(lsub) = lsub.as_ref() else { unreachable!() }; for lpt in lsub.default_params.iter() { - if let Some(rpt) = rsub.default_params.iter().find(|rpt| rpt.name() == lpt.name()) { - if lpt.typ().is_generalized() { continue; } + if let Some(rpt) = rsub + .default_params + .iter() + .find(|rpt| rpt.name() == lpt.name()) + { + if lpt.typ().is_generalized() { + continue; + } // contravariant self.sub_unify(rpt.typ(), lpt.typ(), loc, param_name)?; - } else { todo!() } + } else { + todo!() + } } - lsub.non_default_params.iter().zip(rsub.non_default_params.iter()).try_for_each(|(l, r)| { - if l.typ().is_generalized() { Ok(()) } - // contravariant - else { self.sub_unify(r.typ(), l.typ(), loc, param_name) } - })?; + lsub.non_default_params + .iter() + .zip(rsub.non_default_params.iter()) + .try_for_each(|(l, r)| { + if l.typ().is_generalized() { + Ok(()) + } + // contravariant + else { + self.sub_unify(r.typ(), l.typ(), loc, param_name) + } + })?; // covariant if !lsub.return_t.is_generalized() { self.sub_unify(&lsub.return_t, &rsub.return_t, loc, param_name)?; @@ -1513,17 +1549,31 @@ impl Context { (Type::Subr(lsub), Type::Quantified(rsub)) => { let Type::Subr(rsub) = rsub.as_ref() else { unreachable!() }; for lpt in lsub.default_params.iter() { - if let Some(rpt) = rsub.default_params.iter().find(|rpt| rpt.name() == lpt.name()) { + if let Some(rpt) = rsub + .default_params + .iter() + .find(|rpt| rpt.name() == lpt.name()) + { // contravariant - if rpt.typ().is_generalized() { continue; } + if rpt.typ().is_generalized() { + continue; + } self.sub_unify(rpt.typ(), lpt.typ(), loc, param_name)?; - } else { todo!() } + } else { + todo!() + } } - lsub.non_default_params.iter().zip(rsub.non_default_params.iter()).try_for_each(|(l, r)| { - // contravariant - if r.typ().is_generalized() { Ok(()) } - else { self.sub_unify(r.typ(), l.typ(), loc, param_name) } - })?; + lsub.non_default_params + .iter() + .zip(rsub.non_default_params.iter()) + .try_for_each(|(l, r)| { + // contravariant + if r.typ().is_generalized() { + Ok(()) + } else { + self.sub_unify(r.typ(), l.typ(), loc, param_name) + } + })?; // covariant if !rsub.return_t.is_generalized() { self.sub_unify(&lsub.return_t, &rsub.return_t, loc, param_name)?; @@ -1547,9 +1597,14 @@ impl Context { self.substitute_typarams(sub_def_t, maybe_sub); for sup_trait in sub_ctx.super_traits.iter() { if self.supertype_of(maybe_sup, sup_trait) { - for (l_maybe_sub, r_maybe_sup) in sup_trait.typarams().iter().zip(rps.iter()) { + for (l_maybe_sub, r_maybe_sup) in + sup_trait.typarams().iter().zip(rps.iter()) + { self.sub_unify_tp(l_maybe_sub, r_maybe_sup, None, loc, false) - .map_err(|e| { self.undo_substitute_typarams(sub_def_t); e })?; + .map_err(|e| { + self.undo_substitute_typarams(sub_def_t); + e + })?; } self.undo_substitute_typarams(sub_def_t); return Ok(()); @@ -1582,21 +1637,15 @@ impl Context { self.sub_unify(maybe_sub, r, loc, param_name) } // (X and Y) <: Z is valid when X <: Z or Y <: Z - (Type::And(l, r), _) => { - self.sub_unify(l, maybe_sup, loc, param_name) - .or_else(|_e| self.sub_unify(r, maybe_sup, loc, param_name)) - } + (Type::And(l, r), _) => self + .sub_unify(l, maybe_sup, loc, param_name) + .or_else(|_e| self.sub_unify(r, maybe_sup, loc, param_name)), // X <: (Y or Z) is valid when X <: Y or X <: Z - (_, Type::Or(l, r)) => { - self.sub_unify(maybe_sub, l, loc, param_name) - .or_else(|_e| self.sub_unify(maybe_sub, r, loc, param_name)) - } - (_, Type::Ref(t)) => { - self.sub_unify(maybe_sub, t, loc, param_name) - } - (_, Type::RefMut{ before, .. }) => { - self.sub_unify(maybe_sub, before, loc, param_name) - } + (_, Type::Or(l, r)) => self + .sub_unify(maybe_sub, l, loc, param_name) + .or_else(|_e| self.sub_unify(maybe_sub, r, loc, param_name)), + (_, Type::Ref(t)) => self.sub_unify(maybe_sub, t, loc, param_name), + (_, Type::RefMut { before, .. }) => self.sub_unify(maybe_sub, before, loc, param_name), (Type::Proj { .. }, _) => todo!(), (_, Type::Proj { .. }) => todo!(), // TODO: Judgment for any number of preds @@ -1616,16 +1665,22 @@ impl Context { return Ok(()); } todo!("{sub}, {sup}") - }, + } // {I: Int | I >= 1} <: Nat == {I: Int | I >= 0} (Type::Refinement(_), sup) => { let sup = sup.clone().into_refinement(); self.sub_unify(maybe_sub, &Type::Refinement(sup), loc, param_name) - }, + } (Type::Subr(_) | Type::Record(_), Type) => Ok(()), // REVIEW: correct? - (Type::Poly{ name, .. }, Type) if &name[..] == "Array" || &name[..] == "Tuple" => Ok(()), - _ => todo!("{maybe_sub} can be a subtype of {maybe_sup}, but failed to semi-unify (or existential types are not supported)"), + (Type::Poly { name, .. }, Type) if &name[..] == "Array" || &name[..] == "Tuple" => { + Ok(()) + } + _ => type_feature_error!( + self, + loc, + &format!("{maybe_sub} can be a subtype of {maybe_sup}, but failed to semi-unify") + ), } } } diff --git a/compiler/erg_compiler/error.rs b/compiler/erg_compiler/error.rs index 818d228d..d9cff9a1 100644 --- a/compiler/erg_compiler/error.rs +++ b/compiler/erg_compiler/error.rs @@ -20,6 +20,51 @@ use crate::context::Context; use crate::hir::{Expr, Identifier, Signature}; use crate::ty::{HasType, Predicate, Type}; +/// `unreachable!(self: Context)` +#[macro_export] +macro_rules! unreachable_error { + ($Strcs: ident, $Strc: ident, $ctx: expr) => { + Err($Strcs::from($Strc::unreachable( + $ctx.cfg.input.clone(), + fn_name!(), + line!(), + ))) + }; + ($Strc: ident, $ctx: expr) => { + Err($Strc::unreachable( + $ctx.cfg.input.clone(), + fn_name!(), + line!(), + )) + }; +} +/// `feature_error!($Strc: struct, ctx: Context, loc: Location, name: &str)` +#[macro_export] +macro_rules! feature_error { + ($Strcs: ident, $Strc: ident, $ctx: expr, $loc: expr, $name: expr) => { + Err($Strcs::from($Strc::feature_error( + $ctx.cfg.input.clone(), + $loc, + $name, + $ctx.caused_by(), + ))) + }; + ($Strc: ident, $ctx: expr, $loc: expr, $name: expr) => { + Err($Strc::feature_error( + $ctx.cfg.input.clone(), + $loc, + $name, + $ctx.caused_by(), + )) + }; +} +#[macro_export] +macro_rules! type_feature_error { + ($ctx: expr, $loc: expr, $name: expr) => { + feature_error!(TyCheckErrors, TyCheckError, $ctx, $loc, $name) + }; +} + pub fn ordinal_num(n: usize) -> String { match n.to_string().chars().last().unwrap() { '1' => format!("{n}st"), diff --git a/compiler/erg_compiler/lower.rs b/compiler/erg_compiler/lower.rs index 9ab1aa66..4fcd09ab 100644 --- a/compiler/erg_compiler/lower.rs +++ b/compiler/erg_compiler/lower.rs @@ -40,28 +40,9 @@ use crate::mod_cache::SharedModuleCache; use crate::reorder::Reorderer; use crate::varinfo::{VarInfo, VarKind}; use crate::AccessKind; +use crate::{feature_error, unreachable_error}; use Visibility::*; -macro_rules! unreachable_error { - ($self: ident) => { - Err(LowerErrors::from(LowerError::unreachable( - $self.cfg.input.clone(), - fn_name!(), - line!(), - ))) - }; -} -macro_rules! todo_error { - ($self: ident, $loc: expr, $name: expr) => { - Err(LowerErrors::from(LowerError::feature_error( - $self.cfg.input.clone(), - $loc, - $name, - $self.ctx.caused_by(), - ))) - }; -} - /// Checks & infers types of an AST, and convert (lower) it into a HIR #[derive(Debug)] pub struct ASTLowerer { @@ -337,7 +318,13 @@ impl ASTLowerer { ast::Array::WithLength(arr) => { Ok(hir::Array::WithLength(self.lower_array_with_length(arr)?)) } - other => todo_error!(self, other.loc(), "array comprehension"), + other => feature_error!( + LowerErrors, + LowerError, + self.ctx, + other.loc(), + "array comprehension" + ), } } @@ -622,7 +609,13 @@ impl ASTLowerer { log!(info "enter {}({dict})", fn_name!()); match dict { ast::Dict::Normal(set) => Ok(hir::Dict::Normal(self.lower_normal_dict(set)?)), - other => todo_error!(self, other.loc(), "dict comprehension"), + other => feature_error!( + LowerErrors, + LowerError, + self.ctx, + other.loc(), + "dict comprehension" + ), // ast::Dict::WithLength(set) => Ok(hir::Dict::WithLength(self.lower_dict_with_length(set)?)), } } @@ -726,9 +719,15 @@ impl ASTLowerer { let acc = hir::Accessor::Attr(hir::Attribute::new(obj, ident)); Ok(acc) } - ast::Accessor::TypeApp(t_app) => todo_error!(self, t_app.loc(), "type application"), + ast::Accessor::TypeApp(t_app) => feature_error!( + LowerErrors, + LowerError, + self.ctx, + t_app.loc(), + "type application" + ), // TupleAttr, Subscr are desugared - _ => unreachable!(), + _ => unreachable_error!(LowerErrors, LowerError, self.ctx), } } @@ -1193,7 +1192,7 @@ impl ASTLowerer { let body = hir::DefBody::new(body.op, block, body.id); Ok(hir::Def::new(hir::Signature::Subr(sig), body)) } - _ => unreachable_error!(self), + _ => unreachable_error!(LowerErrors, LowerError, self), } } @@ -1217,7 +1216,7 @@ impl ASTLowerer { )?, tasc.t_spec.loc(), ), - _ => return unreachable_error!(self), + _ => return unreachable_error!(LowerErrors, LowerError, self), }; ( self.ctx.instantiate_typespec( @@ -1339,7 +1338,7 @@ impl ASTLowerer { ) { (dunder_new_vi.t.clone(), new_vi.kind == VarKind::Auto) } else { - return unreachable_error!(self); + return unreachable_error!(LowerErrors, LowerError, self); }; let require_or_sup = self.get_require_or_sup_or_base(hir_def.body.block.remove(0)); Ok(hir::ClassDef::new( @@ -1591,12 +1590,12 @@ impl ASTLowerer { } } other => { - return todo_error!( - self, + return feature_error!( + LowerError, + self.ctx, Location::Unknown, &format!("Impl {other}") - ) - .map_err(|mut e| e.remove(0)); + ); } }, TypeObj::Builtin(_typ) => { diff --git a/compiler/erg_compiler/ty/value.rs b/compiler/erg_compiler/ty/value.rs index ceef3432..e214fbef 100644 --- a/compiler/erg_compiler/ty/value.rs +++ b/compiler/erg_compiler/ty/value.rs @@ -8,8 +8,9 @@ use std::mem; use std::ops::Neg; use std::rc::Rc; +use erg_common::config::Input; use erg_common::dict::Dict; -use erg_common::error::ErrorCore; +use erg_common::error::{ErrorCore, ErrorKind, Location}; use erg_common::fresh::fresh_varname; use erg_common::python_util::PythonVersion; use erg_common::serialize::*; @@ -44,6 +45,18 @@ impl From for ErrorCore { } } +impl EvalValueError { + pub fn feature_error(_input: Input, loc: Location, name: &str, caused_by: String) -> Self { + Self::from(ErrorCore::new( + vec![], + format!("{name} is not supported yet: {caused_by}"), + 0, + ErrorKind::FeatureError, + loc, + )) + } +} + pub type EvalValueResult = Result; #[derive(Clone, Debug, PartialEq, Eq, Hash)]