mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-03 10:23:20 +00:00
fix: param type instantiation bug
This commit is contained in:
parent
0f3d228997
commit
f0e47201bf
5 changed files with 75 additions and 46 deletions
|
@ -389,7 +389,12 @@ impl Context {
|
|||
mode,
|
||||
not_found_is_qvar,
|
||||
)
|
||||
.map_err(|errs| (Type::Failure, errs))?
|
||||
.map_err(|errs| {
|
||||
(
|
||||
opt_decl_t.map_or(Type::Failure, |pt| pt.typ().clone()),
|
||||
errs,
|
||||
)
|
||||
})?
|
||||
} else {
|
||||
match &sig.pat {
|
||||
ast::ParamPattern::Lit(lit) => {
|
||||
|
|
|
@ -1456,6 +1456,25 @@ impl Context {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn get_tv_ctx(&self, ident: &ast::Identifier, args: &ast::Args) -> TyVarCache {
|
||||
let mut tv_ctx = TyVarCache::new(self.level, self);
|
||||
if let Some(ctx) = self.get_type_ctx(ident.inspect()) {
|
||||
let arg_ts = ctx.params.iter().map(|(_, vi)| &vi.t);
|
||||
for ((tp, arg), arg_t) in ctx.typ.typarams().iter().zip(args.pos_args()).zip(arg_ts) {
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
tv_ctx.push_or_init_typaram(&ident.name, tp, self);
|
||||
}
|
||||
}
|
||||
}
|
||||
tv_ctx
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default)]
|
||||
|
|
|
@ -325,6 +325,7 @@ impl Context {
|
|||
&mut self,
|
||||
sig: &mut hir::NonDefaultParamSignature,
|
||||
opt_decl_t: Option<&ParamTy>,
|
||||
tmp_tv_cache: &mut TyVarCache,
|
||||
kind: ParamKind,
|
||||
) -> TyCheckResult<()> {
|
||||
let vis = if PYTHON_MODE {
|
||||
|
@ -341,7 +342,7 @@ impl Context {
|
|||
let (spec_t, errs) = match self.instantiate_param_sig_t(
|
||||
&sig.raw,
|
||||
opt_decl_t,
|
||||
&mut TyVarCache::new(self.level, self),
|
||||
tmp_tv_cache,
|
||||
Normal,
|
||||
kind,
|
||||
false,
|
||||
|
@ -384,11 +385,10 @@ impl Context {
|
|||
)))
|
||||
} else {
|
||||
// ok, not defined
|
||||
let mut dummy_tv_cache = TyVarCache::new(self.level, self);
|
||||
let (spec_t, mut errs) = match self.instantiate_param_sig_t(
|
||||
&sig.raw,
|
||||
opt_decl_t,
|
||||
&mut dummy_tv_cache,
|
||||
tmp_tv_cache,
|
||||
Normal,
|
||||
kind.clone(),
|
||||
false,
|
||||
|
@ -441,11 +441,10 @@ impl Context {
|
|||
)))
|
||||
} else {
|
||||
// ok, not defined
|
||||
let mut dummy_tv_cache = TyVarCache::new(self.level, self);
|
||||
let (spec_t, mut errs) = match self.instantiate_param_sig_t(
|
||||
&sig.raw,
|
||||
opt_decl_t,
|
||||
&mut dummy_tv_cache,
|
||||
tmp_tv_cache,
|
||||
Normal,
|
||||
kind,
|
||||
false,
|
||||
|
@ -494,11 +493,10 @@ impl Context {
|
|||
)))
|
||||
} else {
|
||||
// ok, not defined
|
||||
let mut dummy_tv_cache = TyVarCache::new(self.level, self);
|
||||
let (spec_t, mut errs) = match self.instantiate_param_sig_t(
|
||||
&sig.raw,
|
||||
opt_decl_t,
|
||||
&mut dummy_tv_cache,
|
||||
tmp_tv_cache,
|
||||
Normal,
|
||||
kind,
|
||||
false,
|
||||
|
@ -543,6 +541,7 @@ impl Context {
|
|||
pub(crate) fn assign_params(
|
||||
&mut self,
|
||||
params: &mut hir::Params,
|
||||
tmp_tv_cache: &mut TyVarCache,
|
||||
expect: Option<SubrType>,
|
||||
) -> TyCheckResult<()> {
|
||||
let mut errs = TyCheckErrors::empty();
|
||||
|
@ -570,18 +569,23 @@ impl Context {
|
|||
.iter_mut()
|
||||
.zip(subr_t.non_default_params.iter())
|
||||
{
|
||||
if let Err(es) = self.assign_param(non_default, Some(pt), ParamKind::NonDefault) {
|
||||
if let Err(es) =
|
||||
self.assign_param(non_default, Some(pt), tmp_tv_cache, ParamKind::NonDefault)
|
||||
{
|
||||
errs.extend(es);
|
||||
}
|
||||
}
|
||||
if let Some(var_params) = &mut params.var_params {
|
||||
if let Some(pt) = &subr_t.var_params {
|
||||
let pt = pt.clone().map_type(unknown_len_array_t);
|
||||
if let Err(es) = self.assign_param(var_params, Some(&pt), ParamKind::VarParams)
|
||||
if let Err(es) =
|
||||
self.assign_param(var_params, Some(&pt), tmp_tv_cache, ParamKind::VarParams)
|
||||
{
|
||||
errs.extend(es);
|
||||
}
|
||||
} else if let Err(es) = self.assign_param(var_params, None, ParamKind::VarParams) {
|
||||
} else if let Err(es) =
|
||||
self.assign_param(var_params, None, tmp_tv_cache, ParamKind::VarParams)
|
||||
{
|
||||
errs.extend(es);
|
||||
}
|
||||
}
|
||||
|
@ -589,6 +593,7 @@ impl Context {
|
|||
if let Err(es) = self.assign_param(
|
||||
&mut default.sig,
|
||||
Some(pt),
|
||||
tmp_tv_cache,
|
||||
ParamKind::Default(default.default_val.t()),
|
||||
) {
|
||||
errs.extend(es);
|
||||
|
@ -597,25 +602,32 @@ impl Context {
|
|||
if let Some(kw_var_params) = &mut params.kw_var_params {
|
||||
if let Some(pt) = &subr_t.var_params {
|
||||
let pt = pt.clone().map_type(str_dict_t);
|
||||
if let Err(es) =
|
||||
self.assign_param(kw_var_params, Some(&pt), ParamKind::KwVarParams)
|
||||
{
|
||||
if let Err(es) = self.assign_param(
|
||||
kw_var_params,
|
||||
Some(&pt),
|
||||
tmp_tv_cache,
|
||||
ParamKind::KwVarParams,
|
||||
) {
|
||||
errs.extend(es);
|
||||
}
|
||||
} else if let Err(es) =
|
||||
self.assign_param(kw_var_params, None, ParamKind::KwVarParams)
|
||||
self.assign_param(kw_var_params, None, tmp_tv_cache, ParamKind::KwVarParams)
|
||||
{
|
||||
errs.extend(es);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for non_default in params.non_defaults.iter_mut() {
|
||||
if let Err(es) = self.assign_param(non_default, None, ParamKind::NonDefault) {
|
||||
if let Err(es) =
|
||||
self.assign_param(non_default, None, tmp_tv_cache, ParamKind::NonDefault)
|
||||
{
|
||||
errs.extend(es);
|
||||
}
|
||||
}
|
||||
if let Some(var_params) = &mut params.var_params {
|
||||
if let Err(es) = self.assign_param(var_params, None, ParamKind::VarParams) {
|
||||
if let Err(es) =
|
||||
self.assign_param(var_params, None, tmp_tv_cache, ParamKind::VarParams)
|
||||
{
|
||||
errs.extend(es);
|
||||
}
|
||||
}
|
||||
|
@ -623,13 +635,16 @@ impl Context {
|
|||
if let Err(es) = self.assign_param(
|
||||
&mut default.sig,
|
||||
None,
|
||||
tmp_tv_cache,
|
||||
ParamKind::Default(default.default_val.t()),
|
||||
) {
|
||||
errs.extend(es);
|
||||
}
|
||||
}
|
||||
if let Some(kw_var_params) = &mut params.kw_var_params {
|
||||
if let Err(es) = self.assign_param(kw_var_params, None, ParamKind::KwVarParams) {
|
||||
if let Err(es) =
|
||||
self.assign_param(kw_var_params, None, tmp_tv_cache, ParamKind::KwVarParams)
|
||||
{
|
||||
errs.extend(es);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue