Eliminate todo!s

This commit is contained in:
Shunsuke Shibayama 2022-12-15 15:18:25 +09:00
parent e8e174b1e8
commit 800b6c43d9
8 changed files with 282 additions and 130 deletions

View file

@ -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<ValueObj> {
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<ValueObj> {
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<TyParam>) -> EvalResult<TyParam> {
todo!()
fn eval_app(&self, name: Str, args: Vec<TyParam>) -> EvalResult<TyParam> {
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}")
),
}
}

View file

@ -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<ValueOb
)
})?;
let Some(require) = require.as_type() else {
let require = StyledString::new(&format!("{}", require), Some(ERR), None);
let require = StyledString::new(&format!("{require}"), Some(ERR), None);
return Err(ErrorCore::new(
vec![SubMessage::only_loc(Location::Unknown)],
format!(

View file

@ -29,9 +29,9 @@ use crate::error::{
binop_to_dname, readable_name, unaryop_to_dname, SingleTyCheckResult, TyCheckError,
TyCheckErrors, TyCheckResult,
};
use crate::hir;
use crate::varinfo::{Mutability, VarInfo, VarKind};
use crate::AccessKind;
use crate::{feature_error, hir};
use RegistrationMode::*;
use Visibility::*;
@ -940,8 +940,8 @@ impl Context {
self.substitute_call(obj, attr_name, &fv.crack(), pos_args, kw_args)
}
Type::FreeVar(fv) => {
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()

View file

@ -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<Type> {
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}")),
}
}

View file

@ -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")
),
}
}
}

View file

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

View file

@ -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) => {

View file

@ -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<EvalValueError> 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<T> = Result<T, EvalValueError>;
#[derive(Clone, Debug, PartialEq, Eq, Hash)]