mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 18:58:30 +00:00
feat: eval const call/lambda in refinement types
rename: `Shape` -> `HasShape`
This commit is contained in:
parent
d59a4e82d3
commit
d1fa616aea
11 changed files with 252 additions and 70 deletions
|
@ -20,8 +20,8 @@ use erg_parser::desugar::Desugarer;
|
|||
use erg_parser::token::{Token, TokenKind};
|
||||
|
||||
use crate::ty::constructors::{
|
||||
array_t, bounded, closed_range, dict_t, mono, mono_q, named_free_var, poly, proj, proj_call,
|
||||
ref_, ref_mut, refinement, set_t, subr_t, subtypeof, tp_enum, try_v_enum, tuple_t,
|
||||
array_t, bounded, closed_range, dict_t, func, mono, mono_q, named_free_var, poly, proj,
|
||||
proj_call, ref_, ref_mut, refinement, set_t, subr_t, subtypeof, tp_enum, try_v_enum, tuple_t,
|
||||
unknown_len_array_t, v_enum,
|
||||
};
|
||||
use crate::ty::free::HasLevel;
|
||||
|
@ -34,7 +34,7 @@ use crate::ty::{
|
|||
use crate::context::instantiate_spec::ParamKind;
|
||||
use crate::context::{ClassDefType, Context, ContextKind, RegistrationMode};
|
||||
use crate::error::{EvalError, EvalErrors, EvalResult, SingleEvalResult};
|
||||
use crate::varinfo::VarInfo;
|
||||
use crate::varinfo::{AbsLocation, VarInfo};
|
||||
|
||||
use super::instantiate::TyVarCache;
|
||||
use Type::{Failure, Never, Subr};
|
||||
|
@ -485,10 +485,10 @@ impl Context {
|
|||
}
|
||||
|
||||
fn eval_const_ident(&self, ident: &Identifier) -> EvalResult<ValueObj> {
|
||||
if let Some(val) = self.rec_get_const_obj(ident.inspect()) {
|
||||
Ok(val.clone())
|
||||
} else if let Some(val) = self.get_value_from_tv_cache(ident) {
|
||||
if let Some(val) = self.get_value_from_tv_cache(ident) {
|
||||
Ok(val)
|
||||
} else if let Some(val) = self.rec_get_const_obj(ident.inspect()) {
|
||||
Ok(val.clone())
|
||||
} else if self.kind.is_subr() {
|
||||
feature_error!(self, ident.loc(), "const parameters")
|
||||
} else if ident.is_const() {
|
||||
|
@ -982,6 +982,35 @@ impl Context {
|
|||
self.shared.clone(),
|
||||
self.clone(),
|
||||
);
|
||||
for non_default in non_default_params.iter() {
|
||||
let name = non_default
|
||||
.name()
|
||||
.map(|name| VarName::from_str(name.clone()));
|
||||
let vi = VarInfo::nd_parameter(
|
||||
non_default.typ().clone(),
|
||||
AbsLocation::unknown(),
|
||||
lambda_ctx.name.clone(),
|
||||
);
|
||||
lambda_ctx.params.push((name, vi));
|
||||
}
|
||||
if let Some(var_param) = var_params.as_ref() {
|
||||
let name = var_param.name().map(|name| VarName::from_str(name.clone()));
|
||||
let vi = VarInfo::nd_parameter(
|
||||
var_param.typ().clone(),
|
||||
AbsLocation::unknown(),
|
||||
lambda_ctx.name.clone(),
|
||||
);
|
||||
lambda_ctx.params.push((name, vi));
|
||||
}
|
||||
for default in default_params.iter() {
|
||||
let name = default.name().map(|name| VarName::from_str(name.clone()));
|
||||
let vi = VarInfo::d_parameter(
|
||||
default.typ().clone(),
|
||||
AbsLocation::unknown(),
|
||||
lambda_ctx.name.clone(),
|
||||
);
|
||||
lambda_ctx.params.push((name, vi));
|
||||
}
|
||||
let return_t = v_enum(set! {lambda_ctx.eval_const_block(&lambda.body)?});
|
||||
let sig_t = subr_t(
|
||||
SubrKind::from(lambda.op.kind),
|
||||
|
@ -1444,7 +1473,7 @@ impl Context {
|
|||
Ok(TyParam::app(name, args))
|
||||
}
|
||||
} else {
|
||||
log!(err "eval_app({name}({}))", fmt_vec(&args));
|
||||
log!(err "failed: eval_app({name}({}))", fmt_vec(&args));
|
||||
Ok(TyParam::app(name, args))
|
||||
}
|
||||
}
|
||||
|
@ -1531,13 +1560,15 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
fn _eval_tp_into_value(&self, tp: TyParam) -> EvalResult<ValueObj> {
|
||||
fn eval_tp_into_value(&self, tp: TyParam) -> EvalResult<ValueObj> {
|
||||
self.eval_tp(tp).and_then(|tp| {
|
||||
self.convert_tp_into_value(tp).map_err(|_| {
|
||||
EvalErrors::from(EvalError::unreachable(
|
||||
self.convert_tp_into_value(tp).map_err(|err| {
|
||||
EvalErrors::from(EvalError::feature_error(
|
||||
self.cfg.input.clone(),
|
||||
fn_name!(),
|
||||
line!(),
|
||||
line!() as usize,
|
||||
Location::Unknown,
|
||||
&format!("convert {err} into a value"),
|
||||
self.caused_by(),
|
||||
))
|
||||
})
|
||||
})
|
||||
|
@ -2014,6 +2045,37 @@ impl Context {
|
|||
}
|
||||
Ok(ValueObj::Set(new))
|
||||
}
|
||||
TyParam::App { name, args } => {
|
||||
let mut new = vec![];
|
||||
for elem in args.iter() {
|
||||
let elem = self.convert_tp_into_value(elem.clone())?;
|
||||
new.push(elem);
|
||||
}
|
||||
let Some(ValueObj::Subr(subr)) = self.rec_get_const_obj(&name) else {
|
||||
return Err(TyParam::App { name, args });
|
||||
};
|
||||
let new = ValueArgs::pos_only(new);
|
||||
match self.call(subr.clone(), new, Location::Unknown) {
|
||||
Ok(TyParam::Value(val)) => Ok(val),
|
||||
_ => Err(TyParam::App { name, args }),
|
||||
}
|
||||
}
|
||||
TyParam::Lambda(lambda) => {
|
||||
let name = Str::from("<lambda>");
|
||||
let params = lambda.const_.sig.params;
|
||||
let block = lambda.const_.body;
|
||||
let sig_t = func(
|
||||
lambda.nd_params,
|
||||
lambda.var_params,
|
||||
lambda.d_params,
|
||||
lambda.kw_var_params,
|
||||
// TODO:
|
||||
Type::Obj,
|
||||
);
|
||||
Ok(ValueObj::Subr(ConstSubr::User(UserConstSubr::new(
|
||||
name, params, block, sig_t,
|
||||
))))
|
||||
}
|
||||
other => self.convert_tp_into_type(other).map(ValueObj::builtin_type),
|
||||
}
|
||||
}
|
||||
|
@ -2372,6 +2434,38 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
fn convert_args(
|
||||
&self,
|
||||
lhs: Option<TyParam>,
|
||||
subr: &ConstSubr,
|
||||
args: Vec<TyParam>,
|
||||
t_loc: &impl Locational,
|
||||
) -> EvalResult<ValueArgs> {
|
||||
let mut pos_args = vec![];
|
||||
if subr.sig_t().is_method() {
|
||||
let Some(lhs) = lhs else {
|
||||
return feature_error!(self, t_loc.loc(), "??");
|
||||
};
|
||||
if let Ok(value) = ValueObj::try_from(lhs.clone()) {
|
||||
pos_args.push(value);
|
||||
} else if let Ok(value) = self.eval_tp_into_value(lhs) {
|
||||
pos_args.push(value);
|
||||
} else {
|
||||
return feature_error!(self, t_loc.loc(), "??");
|
||||
}
|
||||
}
|
||||
for pos_arg in args.into_iter() {
|
||||
if let Ok(value) = ValueObj::try_from(pos_arg.clone()) {
|
||||
pos_args.push(value);
|
||||
} else if let Ok(value) = self.eval_tp_into_value(pos_arg) {
|
||||
pos_args.push(value);
|
||||
} else {
|
||||
return feature_error!(self, t_loc.loc(), "??");
|
||||
}
|
||||
}
|
||||
Ok(ValueArgs::new(pos_args, dict! {}))
|
||||
}
|
||||
|
||||
fn do_proj_call(
|
||||
&self,
|
||||
obj: ValueObj,
|
||||
|
@ -2380,28 +2474,7 @@ impl Context {
|
|||
t_loc: &impl Locational,
|
||||
) -> EvalResult<TyParam> {
|
||||
if let ValueObj::Subr(subr) = obj {
|
||||
let mut pos_args = vec![];
|
||||
if subr.sig_t().is_method() {
|
||||
match ValueObj::try_from(lhs) {
|
||||
Ok(value) => {
|
||||
pos_args.push(value);
|
||||
}
|
||||
Err(_) => {
|
||||
return feature_error!(self, t_loc.loc(), "??");
|
||||
}
|
||||
}
|
||||
}
|
||||
for pos_arg in args.into_iter() {
|
||||
match ValueObj::try_from(pos_arg) {
|
||||
Ok(value) => {
|
||||
pos_args.push(value);
|
||||
}
|
||||
Err(_) => {
|
||||
return feature_error!(self, t_loc.loc(), "??");
|
||||
}
|
||||
}
|
||||
}
|
||||
let args = ValueArgs::new(pos_args, dict! {});
|
||||
let args = self.convert_args(Some(lhs), &subr, args, t_loc)?;
|
||||
let tp = self.call(subr, args, t_loc.loc())?;
|
||||
Ok(tp)
|
||||
} else {
|
||||
|
@ -2578,6 +2651,35 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn eval_call(
|
||||
&self,
|
||||
lhs: TyParam,
|
||||
args: Vec<TyParam>,
|
||||
t_loc: &impl Locational,
|
||||
) -> EvalResult<TyParam> {
|
||||
match lhs {
|
||||
/*TyParam::Lambda(lambda) => {
|
||||
todo!("{lambda}")
|
||||
}*/
|
||||
TyParam::Value(ValueObj::Subr(subr)) => {
|
||||
let args = self.convert_args(None, &subr, args, t_loc)?;
|
||||
self.call(subr, args, t_loc.loc())
|
||||
}
|
||||
other => Err(EvalErrors::from(EvalError::type_mismatch_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
t_loc.loc(),
|
||||
self.caused_by(),
|
||||
&other.qual_name().unwrap_or(Str::from("_")),
|
||||
None,
|
||||
&mono("Callable"),
|
||||
&self.get_tp_t(&other).ok().unwrap_or(Type::Obj),
|
||||
None,
|
||||
None,
|
||||
))),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn bool_eval_pred(&self, p: Predicate) -> EvalResult<bool> {
|
||||
let evaled = self.eval_pred(p)?;
|
||||
Ok(matches!(evaled, Predicate::Value(ValueObj::Bool(true))))
|
||||
|
@ -2596,12 +2698,12 @@ impl Context {
|
|||
for arg in args {
|
||||
new_args.push(self.eval_tp(arg)?);
|
||||
}
|
||||
let t = if let Some(name) = name {
|
||||
let tp = if let Some(name) = name {
|
||||
self.eval_proj_call(receiver, name, new_args, &())?
|
||||
} else {
|
||||
return feature_error!(self, Location::Unknown, "eval_pred: Predicate::Call");
|
||||
self.eval_call(receiver, new_args, &())?
|
||||
};
|
||||
if let TyParam::Value(v) = t {
|
||||
if let Ok(v) = self.convert_tp_into_value(tp) {
|
||||
Ok(Predicate::Value(v))
|
||||
} else {
|
||||
feature_error!(self, Location::Unknown, "eval_pred: Predicate::Call")
|
||||
|
|
|
@ -676,7 +676,7 @@ impl<'c, 'q, 'l, L: Locational> Dereferencer<'c, 'q, 'l, L> {
|
|||
self.ctx
|
||||
.eval_proj_call(receiver.clone(), name.clone(), new_args.clone(), &())
|
||||
} else {
|
||||
return Ok(Predicate::call(receiver, name, new_args));
|
||||
self.ctx.eval_call(receiver.clone(), new_args.clone(), &())
|
||||
};
|
||||
match evaled {
|
||||
Ok(TyParam::Value(value)) => Ok(Predicate::Value(value)),
|
||||
|
|
|
@ -1516,7 +1516,7 @@ impl Context {
|
|||
.register_marker_trait(
|
||||
self,
|
||||
poly(
|
||||
SHAPE,
|
||||
HAS_SHAPE,
|
||||
vec![ty_tp(arr_t.clone()).proj_call(FUNC_SHAPE.into(), vec![])],
|
||||
),
|
||||
)
|
||||
|
|
|
@ -98,7 +98,7 @@ const COLLECTION: &str = "Collection";
|
|||
const INDEXABLE: &str = "Indexable";
|
||||
const MAPPING: &str = "Mapping";
|
||||
const MUTABLE_MAPPING: &str = "Mapping!";
|
||||
const SHAPE: &str = "Shape";
|
||||
const HAS_SHAPE: &str = "HasShape";
|
||||
const EQ: &str = "Eq";
|
||||
const HASH: &str = "Hash";
|
||||
const EQ_HASH: &str = "EqHash";
|
||||
|
|
|
@ -356,10 +356,10 @@ impl Context {
|
|||
Visibility::BUILTIN_PUBLIC,
|
||||
Some(FUNDAMENTAL_EXIT),
|
||||
);
|
||||
/* Shape */
|
||||
/* HasShape */
|
||||
let S = mono_q_tp(TY_S, instanceof(unknown_len_array_t(Nat)));
|
||||
let params = vec![PS::named_nd("S", unknown_len_array_t(Nat))];
|
||||
let shape = Self::builtin_poly_trait(SHAPE, params.clone(), 2);
|
||||
let has_shape = Self::builtin_poly_trait(HAS_SHAPE, params.clone(), 2);
|
||||
/* Num */
|
||||
let R = mono_q(TY_R, instanceof(Type));
|
||||
let params = vec![PS::t(TY_R, false, WithDefault)];
|
||||
|
@ -551,7 +551,13 @@ impl Context {
|
|||
Const,
|
||||
None,
|
||||
);
|
||||
self.register_builtin_type(poly(SHAPE, vec![S]), shape, vis.clone(), Const, None);
|
||||
self.register_builtin_type(
|
||||
poly(HAS_SHAPE, vec![S]),
|
||||
has_shape,
|
||||
vis.clone(),
|
||||
Const,
|
||||
None,
|
||||
);
|
||||
self.register_builtin_type(poly(ADD, ty_params.clone()), add, vis.clone(), Const, None);
|
||||
self.register_builtin_type(poly(SUB, ty_params.clone()), sub, vis.clone(), Const, None);
|
||||
self.register_builtin_type(poly(MUL, ty_params.clone()), mul, vis.clone(), Const, None);
|
||||
|
|
|
@ -158,9 +158,14 @@ impl TyVarCache {
|
|||
self.already_appeared.insert(name);
|
||||
}
|
||||
|
||||
pub(crate) fn push_or_init_tyvar(&mut self, name: &VarName, tv: &Type, ctx: &Context) {
|
||||
pub(crate) fn push_or_init_tyvar(
|
||||
&mut self,
|
||||
name: &VarName,
|
||||
tv: &Type,
|
||||
ctx: &Context,
|
||||
) -> TyCheckResult<()> {
|
||||
if name.inspect() == "_" {
|
||||
return;
|
||||
return Ok(());
|
||||
}
|
||||
if let Some(inst) = self.tyvar_instances.get(name) {
|
||||
self.update_tyvar(inst, tv, ctx);
|
||||
|
@ -178,6 +183,7 @@ impl TyVarCache {
|
|||
ctx.index().register(name.inspect().clone(), &vi);
|
||||
self.var_infos.insert(name.clone(), vi);
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn dummy_push_or_init_tyvar(&mut self, name: &VarName, tv: &Type, ctx: &Context) {
|
||||
|
@ -235,9 +241,24 @@ impl TyVarCache {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) fn push_or_init_typaram(&mut self, name: &VarName, tp: &TyParam, ctx: &Context) {
|
||||
pub(crate) fn push_or_init_typaram(
|
||||
&mut self,
|
||||
name: &VarName,
|
||||
tp: &TyParam,
|
||||
ctx: &Context,
|
||||
) -> TyCheckResult<()> {
|
||||
if name.inspect() == "_" {
|
||||
return;
|
||||
return Ok(());
|
||||
}
|
||||
if ctx.rec_get_const_obj(name.inspect()).is_some() {
|
||||
return Err(TyCheckError::reassign_error(
|
||||
ctx.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
name.loc(),
|
||||
ctx.caused_by(),
|
||||
name.inspect(),
|
||||
)
|
||||
.into());
|
||||
}
|
||||
// FIXME:
|
||||
if let Some(inst) = self.typaram_instances.get(name) {
|
||||
|
@ -255,6 +276,7 @@ impl TyVarCache {
|
|||
self.var_infos.insert(name.clone(), vi);
|
||||
self.typaram_instances.insert(name.clone(), tp.clone());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn push_refine_var(&mut self, name: &VarName, t: Type, ctx: &Context) {
|
||||
|
|
|
@ -22,6 +22,7 @@ use crate::ty::value::ValueObj;
|
|||
use crate::ty::{constructors::*, Predicate, RefinementType, VisibilityModifier};
|
||||
use crate::ty::{Field, HasType, ParamTy, SubrKind, SubrType, Type};
|
||||
use crate::type_feature_error;
|
||||
use crate::varinfo::{AbsLocation, VarInfo};
|
||||
use TyParamOrdering::*;
|
||||
use Type::*;
|
||||
|
||||
|
@ -125,8 +126,7 @@ impl Context {
|
|||
// TODO: other than type `Type`
|
||||
let constr = Constraint::new_type_of(Type);
|
||||
let tv = named_free_var(name.inspect().clone(), self.level, constr);
|
||||
tv_cache.push_or_init_tyvar(name, &tv, self);
|
||||
Ok(())
|
||||
tv_cache.push_or_init_tyvar(name, &tv, self)
|
||||
}
|
||||
TypeBoundSpec::NonDefault { lhs, spec } => {
|
||||
let constr = match spec.op.kind {
|
||||
|
@ -147,10 +147,10 @@ impl Context {
|
|||
};
|
||||
if constr.get_sub_sup().is_none() {
|
||||
let tp = TyParam::named_free_var(lhs.inspect().clone(), self.level, constr);
|
||||
tv_cache.push_or_init_typaram(lhs, &tp, self);
|
||||
tv_cache.push_or_init_typaram(lhs, &tp, self)?;
|
||||
} else {
|
||||
let tv = named_free_var(lhs.inspect().clone(), self.level, constr);
|
||||
tv_cache.push_or_init_tyvar(lhs, &tv, self);
|
||||
tv_cache.push_or_init_tyvar(lhs, &tv, self)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -642,7 +642,7 @@ impl Context {
|
|||
Ok(ctx.typ.clone())
|
||||
} else if not_found_is_qvar {
|
||||
let tyvar = named_free_var(Str::rc(other), self.level, Constraint::Uninited);
|
||||
tmp_tv_cache.push_or_init_tyvar(&ident.name, &tyvar, self);
|
||||
tmp_tv_cache.push_or_init_tyvar(&ident.name, &tyvar, self)?;
|
||||
Ok(tyvar)
|
||||
} else if let Some(decl_t) = opt_decl_t {
|
||||
Ok(decl_t.typ().clone())
|
||||
|
@ -836,7 +836,7 @@ impl Context {
|
|||
Constraint::Uninited,
|
||||
);
|
||||
let varname = VarName::from_str(name);
|
||||
tmp_tv_cache.push_or_init_typaram(&varname, &tp, self);
|
||||
tmp_tv_cache.push_or_init_typaram(&varname, &tp, self)?;
|
||||
Ok(tp)
|
||||
} else {
|
||||
Err(e)
|
||||
|
@ -946,9 +946,15 @@ impl Context {
|
|||
}
|
||||
if not_found_is_qvar {
|
||||
let tyvar = named_free_var(name.inspect().clone(), self.level, Constraint::Uninited);
|
||||
tmp_tv_cache.push_or_init_tyvar(&name.name, &tyvar, self);
|
||||
tmp_tv_cache.push_or_init_tyvar(&name.name, &tyvar, self)?;
|
||||
return Ok(TyParam::t(tyvar));
|
||||
}
|
||||
if name.is_const() {
|
||||
if let Some((_, vi)) = self.get_var_info(name.inspect()) {
|
||||
self.inc_ref(name.inspect(), vi, name, self);
|
||||
return Ok(TyParam::mono(name.inspect()));
|
||||
}
|
||||
}
|
||||
Err(TyCheckErrors::from(TyCheckError::no_var_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
|
@ -1227,10 +1233,50 @@ impl Context {
|
|||
} else {
|
||||
None
|
||||
};
|
||||
let mut lambda_ctx = Context::instant(
|
||||
Str::ever("<lambda>"),
|
||||
self.cfg.clone(),
|
||||
0,
|
||||
self.shared.clone(),
|
||||
self.clone(),
|
||||
);
|
||||
for non_default in nd_params.iter() {
|
||||
let name = non_default
|
||||
.name()
|
||||
.map(|name| VarName::from_str(name.clone()));
|
||||
let vi = VarInfo::nd_parameter(
|
||||
non_default.typ().clone(),
|
||||
AbsLocation::unknown(),
|
||||
lambda_ctx.name.clone(),
|
||||
);
|
||||
lambda_ctx.params.push((name, vi));
|
||||
}
|
||||
if let Some(var_param) = var_params.as_ref() {
|
||||
let name = var_param.name().map(|name| VarName::from_str(name.clone()));
|
||||
let vi = VarInfo::nd_parameter(
|
||||
var_param.typ().clone(),
|
||||
AbsLocation::unknown(),
|
||||
lambda_ctx.name.clone(),
|
||||
);
|
||||
lambda_ctx.params.push((name, vi));
|
||||
}
|
||||
for default in d_params.iter() {
|
||||
let name = default.name().map(|name| VarName::from_str(name.clone()));
|
||||
let vi = VarInfo::d_parameter(
|
||||
default.typ().clone(),
|
||||
AbsLocation::unknown(),
|
||||
lambda_ctx.name.clone(),
|
||||
);
|
||||
lambda_ctx.params.push((name, vi));
|
||||
}
|
||||
let mut body = vec![];
|
||||
for expr in lambda.body.iter() {
|
||||
let param =
|
||||
self.instantiate_const_expr(expr, None, tmp_tv_cache, not_found_is_qvar)?;
|
||||
let param = lambda_ctx.instantiate_const_expr(
|
||||
expr,
|
||||
None,
|
||||
tmp_tv_cache,
|
||||
not_found_is_qvar,
|
||||
)?;
|
||||
body.push(param);
|
||||
}
|
||||
tmp_tv_cache.purge(&_tmp_tv_cache);
|
||||
|
|
|
@ -1465,11 +1465,11 @@ impl Context {
|
|||
if let ast::Expr::Accessor(ast::Accessor::Ident(ident)) = &arg.expr {
|
||||
if self.subtype_of(arg_t, &Type::Type) {
|
||||
if let Ok(tv) = self.convert_tp_into_type(tp.clone()) {
|
||||
tv_ctx.push_or_init_tyvar(&ident.name, &tv, self);
|
||||
let _ = tv_ctx.push_or_init_tyvar(&ident.name, &tv, self);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
tv_ctx.push_or_init_typaram(&ident.name, tp, self);
|
||||
let _ = tv_ctx.push_or_init_typaram(&ident.name, tp, self);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -366,10 +366,12 @@ impl<'c, 'l, 'u, L: Locational> Unifier<'c, 'l, 'u, L> {
|
|||
maybe_sub.link(sup_tp, self.undoable);
|
||||
Ok(())
|
||||
} else {
|
||||
Err(TyCheckErrors::from(TyCheckError::unreachable(
|
||||
Err(TyCheckErrors::from(TyCheckError::feature_error(
|
||||
self.ctx.cfg.input.clone(),
|
||||
fn_name!(),
|
||||
line!(),
|
||||
line!() as usize,
|
||||
self.loc.loc(),
|
||||
&format!("unifying {sub_fv} and {sup_tp}"),
|
||||
self.ctx.caused_by(),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
@ -412,10 +414,12 @@ impl<'c, 'l, 'u, L: Locational> Unifier<'c, 'l, 'u, L> {
|
|||
// self.sub_unify(&tp_t, &fv_t)
|
||||
Ok(())
|
||||
} else {
|
||||
Err(TyCheckErrors::from(TyCheckError::unreachable(
|
||||
Err(TyCheckErrors::from(TyCheckError::feature_error(
|
||||
self.ctx.cfg.input.clone(),
|
||||
fn_name!(),
|
||||
line!(),
|
||||
line!() as usize,
|
||||
self.loc.loc(),
|
||||
&format!("unifying {sub_tp} and {sup_fv}"),
|
||||
self.ctx.caused_by(),
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
@ -523,10 +527,12 @@ impl<'c, 'l, 'u, L: Locational> Unifier<'c, 'l, 'u, L> {
|
|||
} else {
|
||||
log!(err "{sup} does not have key {sub_k}");
|
||||
// TODO:
|
||||
return Err(TyCheckErrors::from(TyCheckError::unreachable(
|
||||
return Err(TyCheckErrors::from(TyCheckError::feature_error(
|
||||
self.ctx.cfg.input.clone(),
|
||||
fn_name!(),
|
||||
line!(),
|
||||
line!() as usize,
|
||||
self.loc.loc(),
|
||||
&format!("unifying {sub} and {sup}"),
|
||||
self.ctx.caused_by(),
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@
|
|||
.all: |T <: Num|(object: .NDArray(T),) -> Bool
|
||||
.any: |T <: Num|(object: .NDArray(T),) -> Bool
|
||||
.arange: |T <: Num|(start: T, stop := T, step := T) -> .NDArray(T)
|
||||
.array: |T, S: [Nat; _]|(object: Iterable(T) and Shape(S),) -> .NDArray(T, S)
|
||||
.array: |T, S: [Nat; _]|(object: Iterable(T) and HasShape(S),) -> .NDArray(T, S)
|
||||
.linspace: |T <: Num|(start: T, stop: T, num := Nat, endpoint := Bool, retstep := Bool, dtype := Type, axis := Nat) -> .NDArray(T)
|
||||
.max: |T <: Num|(object: .NDArray(T),) -> T
|
||||
.mean: |T <: Num|(object: .NDArray(T),) -> T
|
||||
|
|
|
@ -1785,13 +1785,13 @@ impl NestedDisplay for Call {
|
|||
}
|
||||
|
||||
impl TryFrom<Expr> for Call {
|
||||
type Error = Expr;
|
||||
type Error = ();
|
||||
fn try_from(expr: Expr) -> Result<Self, Self::Error> {
|
||||
match expr {
|
||||
Expr::Call(call) => Ok(call),
|
||||
Expr::TypeAscription(tasc) => Self::try_from(*tasc.expr),
|
||||
Expr::Accessor(Accessor::TypeApp(tapp)) => Self::try_from(*tapp.obj),
|
||||
_ => Err(expr),
|
||||
_ => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue