mirror of
https://github.com/erg-lang/erg.git
synced 2025-10-03 05:54:33 +00:00
Fix Context::eval_t_params
This commit is contained in:
parent
0262e6de69
commit
ad363bed6a
3 changed files with 69 additions and 30 deletions
|
@ -1,6 +1,7 @@
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
|
||||||
use erg_common::dict::Dict;
|
use erg_common::dict::Dict;
|
||||||
|
use erg_common::error::Location;
|
||||||
use erg_common::rccell::RcCell;
|
use erg_common::rccell::RcCell;
|
||||||
use erg_common::set::Set;
|
use erg_common::set::Set;
|
||||||
use erg_common::traits::{Locational, Stream};
|
use erg_common::traits::{Locational, Stream};
|
||||||
|
@ -496,21 +497,28 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn eval_t_params(&self, substituted: Type, level: usize) -> EvalResult<Type> {
|
pub(crate) fn eval_t_params(
|
||||||
|
&self,
|
||||||
|
substituted: Type,
|
||||||
|
level: usize,
|
||||||
|
t_loc: Location,
|
||||||
|
) -> EvalResult<Type> {
|
||||||
match substituted {
|
match substituted {
|
||||||
Type::FreeVar(fv) if fv.is_linked() => self.eval_t_params(fv.crack().clone(), level),
|
Type::FreeVar(fv) if fv.is_linked() => {
|
||||||
|
self.eval_t_params(fv.crack().clone(), level, t_loc)
|
||||||
|
}
|
||||||
Type::Subr(mut subr) => {
|
Type::Subr(mut subr) => {
|
||||||
for pt in subr.non_default_params.iter_mut() {
|
for pt in subr.non_default_params.iter_mut() {
|
||||||
*pt.typ_mut() = self.eval_t_params(mem::take(pt.typ_mut()), level)?;
|
*pt.typ_mut() = self.eval_t_params(mem::take(pt.typ_mut()), level, t_loc)?;
|
||||||
}
|
}
|
||||||
if let Some(var_args) = subr.var_params.as_mut() {
|
if let Some(var_args) = subr.var_params.as_mut() {
|
||||||
*var_args.typ_mut() =
|
*var_args.typ_mut() =
|
||||||
self.eval_t_params(mem::take(var_args.typ_mut()), level)?;
|
self.eval_t_params(mem::take(var_args.typ_mut()), level, t_loc)?;
|
||||||
}
|
}
|
||||||
for pt in subr.default_params.iter_mut() {
|
for pt in subr.default_params.iter_mut() {
|
||||||
*pt.typ_mut() = self.eval_t_params(mem::take(pt.typ_mut()), level)?;
|
*pt.typ_mut() = self.eval_t_params(mem::take(pt.typ_mut()), level, t_loc)?;
|
||||||
}
|
}
|
||||||
let return_t = self.eval_t_params(*subr.return_t, level)?;
|
let return_t = self.eval_t_params(*subr.return_t, level, t_loc)?;
|
||||||
Ok(subr_t(
|
Ok(subr_t(
|
||||||
subr.kind,
|
subr.kind,
|
||||||
subr.non_default_params,
|
subr.non_default_params,
|
||||||
|
@ -533,7 +541,7 @@ impl Context {
|
||||||
// All type variables will be dereferenced or fail.
|
// All type variables will be dereferenced or fail.
|
||||||
let (sub, opt_sup) = match *lhs.clone() {
|
let (sub, opt_sup) = match *lhs.clone() {
|
||||||
Type::FreeVar(fv) if fv.is_linked() => {
|
Type::FreeVar(fv) if fv.is_linked() => {
|
||||||
return self.eval_t_params(mono_proj(fv.crack().clone(), rhs), level)
|
return self.eval_t_params(mono_proj(fv.crack().clone(), rhs), level, t_loc)
|
||||||
}
|
}
|
||||||
Type::FreeVar(fv) if fv.is_unbound() => {
|
Type::FreeVar(fv) if fv.is_unbound() => {
|
||||||
let (sub, sup) = fv.get_bound_types().unwrap();
|
let (sub, sup) = fv.get_bound_types().unwrap();
|
||||||
|
@ -553,7 +561,7 @@ impl Context {
|
||||||
if let ValueObj::Type(quant_t) = obj {
|
if let ValueObj::Type(quant_t) = obj {
|
||||||
let subst_ctx = SubstContext::new(&sub, ty_ctx);
|
let subst_ctx = SubstContext::new(&sub, ty_ctx);
|
||||||
let t = subst_ctx.substitute(quant_t.typ().clone(), self)?;
|
let t = subst_ctx.substitute(quant_t.typ().clone(), self)?;
|
||||||
let t = self.eval_t_params(t, level)?;
|
let t = self.eval_t_params(t, level, t_loc)?;
|
||||||
return Ok(t);
|
return Ok(t);
|
||||||
} else {
|
} else {
|
||||||
todo!()
|
todo!()
|
||||||
|
@ -577,7 +585,7 @@ impl Context {
|
||||||
if let ValueObj::Type(quant_t) = obj {
|
if let ValueObj::Type(quant_t) = obj {
|
||||||
let subst_ctx = SubstContext::new(&lhs, ty_ctx);
|
let subst_ctx = SubstContext::new(&lhs, ty_ctx);
|
||||||
let t = subst_ctx.substitute(quant_t.typ().clone(), self)?;
|
let t = subst_ctx.substitute(quant_t.typ().clone(), self)?;
|
||||||
let t = self.eval_t_params(t, level)?;
|
let t = self.eval_t_params(t, level, t_loc)?;
|
||||||
return Ok(t);
|
return Ok(t);
|
||||||
} else {
|
} else {
|
||||||
todo!()
|
todo!()
|
||||||
|
@ -585,20 +593,18 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
todo!(
|
Err(EvalError::no_candidate_error(
|
||||||
"{lhs}.{rhs} not found in [{}]",
|
line!() as usize,
|
||||||
erg_common::fmt_iter(
|
&mono_proj(*lhs, rhs),
|
||||||
self.get_nominal_super_type_ctxs(&lhs)
|
t_loc,
|
||||||
.unwrap()
|
self.caused_by(),
|
||||||
.map(|(_, ctx)| &ctx.name)
|
))
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
Type::Ref(l) => Ok(ref_(self.eval_t_params(*l, level)?)),
|
Type::Ref(l) => Ok(ref_(self.eval_t_params(*l, level, t_loc)?)),
|
||||||
Type::RefMut { before, after } => {
|
Type::RefMut { before, after } => {
|
||||||
let before = self.eval_t_params(*before, level)?;
|
let before = self.eval_t_params(*before, level, t_loc)?;
|
||||||
let after = if let Some(after) = after {
|
let after = if let Some(after) = after {
|
||||||
Some(self.eval_t_params(*after, level)?)
|
Some(self.eval_t_params(*after, level, t_loc)?)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
@ -615,17 +621,23 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn _eval_bound(&self, bound: TyBound, level: usize) -> EvalResult<TyBound> {
|
pub(crate) fn _eval_bound(
|
||||||
|
&self,
|
||||||
|
bound: TyBound,
|
||||||
|
level: usize,
|
||||||
|
t_loc: Location,
|
||||||
|
) -> EvalResult<TyBound> {
|
||||||
match bound {
|
match bound {
|
||||||
TyBound::Sandwiched { sub, mid, sup } => {
|
TyBound::Sandwiched { sub, mid, sup } => {
|
||||||
let sub = self.eval_t_params(sub, level)?;
|
let sub = self.eval_t_params(sub, level, t_loc)?;
|
||||||
let mid = self.eval_t_params(mid, level)?;
|
let mid = self.eval_t_params(mid, level, t_loc)?;
|
||||||
let sup = self.eval_t_params(sup, level)?;
|
let sup = self.eval_t_params(sup, level, t_loc)?;
|
||||||
Ok(TyBound::sandwiched(sub, mid, sup))
|
Ok(TyBound::sandwiched(sub, mid, sup))
|
||||||
}
|
}
|
||||||
TyBound::Instance { name: inst, t } => {
|
TyBound::Instance { name: inst, t } => Ok(TyBound::instance(
|
||||||
Ok(TyBound::instance(inst, self.eval_t_params(t, level)?))
|
inst,
|
||||||
}
|
self.eval_t_params(t, level, t_loc)?,
|
||||||
|
)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -956,7 +956,7 @@ impl Context {
|
||||||
);
|
);
|
||||||
self.substitute_call(obj, method_name, &instance, pos_args, kw_args)?;
|
self.substitute_call(obj, method_name, &instance, pos_args, kw_args)?;
|
||||||
log!(info "Substituted:\ninstance: {instance}");
|
log!(info "Substituted:\ninstance: {instance}");
|
||||||
let res = self.eval_t_params(instance, self.level)?;
|
let res = self.eval_t_params(instance, self.level, obj.loc())?;
|
||||||
log!(info "Params evaluated:\nres: {res}\n");
|
log!(info "Params evaluated:\nres: {res}\n");
|
||||||
self.propagate(&res, obj)?;
|
self.propagate(&res, obj)?;
|
||||||
log!(info "Propagated:\nres: {res}\n");
|
log!(info "Propagated:\nres: {res}\n");
|
||||||
|
@ -1520,8 +1520,12 @@ impl Context {
|
||||||
let candidates = insts.into_iter().filter_map(move |inst| {
|
let candidates = insts.into_iter().filter_map(move |inst| {
|
||||||
if self.supertype_of(&inst.sup_trait, &sup) {
|
if self.supertype_of(&inst.sup_trait, &sup) {
|
||||||
Some(
|
Some(
|
||||||
self.eval_t_params(mono_proj(inst.sub_type, rhs), self.level)
|
self.eval_t_params(
|
||||||
.unwrap(),
|
mono_proj(inst.sub_type, rhs),
|
||||||
|
self.level,
|
||||||
|
Location::Unknown,
|
||||||
|
)
|
||||||
|
.unwrap(),
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
@ -1139,6 +1139,29 @@ passed keyword args: {RED}{kw_args_len}{RESET}"
|
||||||
caused_by,
|
caused_by,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn no_candidate_error(
|
||||||
|
errno: usize,
|
||||||
|
proj: &Type,
|
||||||
|
loc: Location,
|
||||||
|
caused_by: AtomicStr,
|
||||||
|
) -> Self {
|
||||||
|
Self::new(
|
||||||
|
ErrorCore::new(
|
||||||
|
errno,
|
||||||
|
TypeError,
|
||||||
|
loc,
|
||||||
|
switch_lang!(
|
||||||
|
"japanese" => format!("{proj}の候補がありません"),
|
||||||
|
"simplified_chinese" => format!("{proj}没有候选项"),
|
||||||
|
"traditional_chinese" => format!("{proj}沒有候選項"),
|
||||||
|
"english" => format!("no candidate for {proj}"),
|
||||||
|
),
|
||||||
|
None,
|
||||||
|
),
|
||||||
|
caused_by,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue