fix: param type instantiation bug

This commit is contained in:
Shunsuke Shibayama 2024-01-29 13:20:40 +09:00
parent 0f3d228997
commit f0e47201bf
5 changed files with 75 additions and 46 deletions

View file

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

View file

@ -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)]

View file

@ -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);
}
}