mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 18:58:30 +00:00
fix: #442
This commit is contained in:
parent
4dff4746b8
commit
9308a910ca
8 changed files with 140 additions and 68 deletions
|
@ -21,7 +21,7 @@ use crate::ty::constructors::{
|
|||
array_t, dict_t, mono, poly, proj, proj_call, ref_, ref_mut, refinement, set_t, subr_t,
|
||||
tp_enum, tuple_t, v_enum,
|
||||
};
|
||||
use crate::ty::free::{FreeTyVar, HasLevel};
|
||||
use crate::ty::free::{Constraint, FreeTyVar, HasLevel};
|
||||
use crate::ty::typaram::{OpKind, TyParam};
|
||||
use crate::ty::value::{GenTypeObj, TypeObj, ValueObj};
|
||||
use crate::ty::{ConstSubr, HasType, Predicate, SubrKind, Type, UserConstSubr, ValueArgs};
|
||||
|
@ -1035,7 +1035,22 @@ impl Context {
|
|||
}
|
||||
Ok(TyParam::Set(new_set))
|
||||
}
|
||||
TyParam::Type(_) | TyParam::Erased(_) | TyParam::Value(_) => Ok(p.clone()),
|
||||
TyParam::Type(t) => self
|
||||
.eval_t_params(*t, self.level, &())
|
||||
.map(TyParam::t)
|
||||
.map_err(|(_, errs)| errs),
|
||||
TyParam::Erased(t) => self
|
||||
.eval_t_params(*t, self.level, &())
|
||||
.map(TyParam::erased)
|
||||
.map_err(|(_, errs)| errs),
|
||||
TyParam::Value(ValueObj::Type(mut t)) => {
|
||||
t.try_map_t(|t| {
|
||||
self.eval_t_params(t, self.level, &())
|
||||
.map_err(|(_, errs)| errs)
|
||||
})?;
|
||||
Ok(TyParam::Value(ValueObj::Type(t)))
|
||||
}
|
||||
TyParam::Value(_) => Ok(p.clone()),
|
||||
_other => feature_error!(self, Location::Unknown, "???"),
|
||||
}
|
||||
}
|
||||
|
@ -1052,6 +1067,22 @@ impl Context {
|
|||
Type::FreeVar(fv) if fv.is_linked() => {
|
||||
self.eval_t_params(fv.crack().clone(), level, t_loc)
|
||||
}
|
||||
Type::FreeVar(fv) if fv.constraint_is_sandwiched() => {
|
||||
let (sub, sup) = fv.get_subsup().unwrap();
|
||||
let sub = if sub.is_recursive() {
|
||||
sub
|
||||
} else {
|
||||
self.eval_t_params(sub, level, t_loc)?
|
||||
};
|
||||
let sup = if sup.is_recursive() {
|
||||
sup
|
||||
} else {
|
||||
self.eval_t_params(sup, level, t_loc)?
|
||||
};
|
||||
let new_constraint = Constraint::new_sandwiched(sub, sup);
|
||||
fv.update_constraint(new_constraint, false);
|
||||
Ok(Type::FreeVar(fv))
|
||||
}
|
||||
Type::Subr(mut subr) => {
|
||||
for pt in subr.non_default_params.iter_mut() {
|
||||
*pt.typ_mut() = match self.eval_t_params(mem::take(pt.typ_mut()), level, t_loc)
|
||||
|
@ -1319,6 +1350,7 @@ impl Context {
|
|||
|
||||
/// ```erg
|
||||
/// TyParam::Type(Int) => Int
|
||||
/// [{1}, {2}, {3}] => [{1, 2, 3}; 3]
|
||||
/// (Int, Str) => Tuple([Int, Str])
|
||||
/// {x = Int; y = Int} => Type::Record({x = Int, y = Int})
|
||||
/// {Str: Int} => Dict({Str: Int})
|
||||
|
@ -1333,6 +1365,14 @@ impl Context {
|
|||
}
|
||||
Ok(tuple_t(ts))
|
||||
}
|
||||
TyParam::Array(tps) => {
|
||||
let mut union = Type::Never;
|
||||
let len = tps.len();
|
||||
for tp in tps {
|
||||
union = self.union(&union, &self.convert_tp_into_type(tp)?);
|
||||
}
|
||||
Ok(array_t(union, TyParam::value(len)))
|
||||
}
|
||||
TyParam::Set(tps) => {
|
||||
let mut union = Type::Never;
|
||||
for tp in tps.iter() {
|
||||
|
@ -1802,6 +1842,46 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
fn do_proj_call(
|
||||
&self,
|
||||
obj: ValueObj,
|
||||
lhs: TyParam,
|
||||
args: Vec<TyParam>,
|
||||
t_loc: &impl Locational,
|
||||
) -> EvalResult<Type> {
|
||||
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 t = self.call(subr, args, t_loc.loc())?;
|
||||
let t = self
|
||||
.convert_value_into_type(t)
|
||||
.unwrap_or_else(|value| todo!("Type::try_from {value}"));
|
||||
Ok(t)
|
||||
} else {
|
||||
feature_error!(self, t_loc.loc(), "??")
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn eval_proj_call(
|
||||
&self,
|
||||
lhs: TyParam,
|
||||
|
@ -1821,61 +1901,11 @@ impl Context {
|
|||
)
|
||||
})? {
|
||||
if let Ok(obj) = ty_ctx.get_const_local(&Token::symbol(&attr_name), &self.name) {
|
||||
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 t = self.call(subr, args, t_loc.loc())?;
|
||||
let t = self
|
||||
.convert_value_into_type(t)
|
||||
.unwrap_or_else(|value| todo!("Type::try_from {value}"));
|
||||
return Ok(t);
|
||||
} else {
|
||||
return feature_error!(self, t_loc.loc(), "??");
|
||||
}
|
||||
return self.do_proj_call(obj, lhs, args, t_loc);
|
||||
}
|
||||
for (_class, methods) in ty_ctx.methods_list.iter() {
|
||||
if let Ok(obj) = methods.get_const_local(&Token::symbol(&attr_name), &self.name) {
|
||||
if let ValueObj::Subr(subr) = obj {
|
||||
let mut pos_args = vec![];
|
||||
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 t = self.call(subr, args, t_loc.loc())?;
|
||||
let t = self
|
||||
.convert_value_into_type(t)
|
||||
.unwrap_or_else(|value| todo!("Type::try_from {value}"));
|
||||
return Ok(t);
|
||||
} else {
|
||||
return feature_error!(self, t_loc.loc(), "??");
|
||||
}
|
||||
return self.do_proj_call(obj, lhs, args, t_loc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue