mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-30 04:44:44 +00:00
Fix kw args bugs & add a test
This commit is contained in:
parent
38d69e6b96
commit
2f7d810685
3 changed files with 54 additions and 16 deletions
|
@ -1019,6 +1019,20 @@ impl Context {
|
|||
}
|
||||
} else {
|
||||
// pos_args.len() < non_default_params_len
|
||||
let mut params = non_default_params.chain(subr.default_params.iter());
|
||||
for pos_arg in pos_args.iter() {
|
||||
if let Err(mut es) = self.substitute_pos_arg(
|
||||
&callee,
|
||||
attr_name,
|
||||
&pos_arg.expr,
|
||||
nth,
|
||||
params.next().unwrap(),
|
||||
&mut passed_params,
|
||||
) {
|
||||
errs.append(&mut es);
|
||||
}
|
||||
nth += 1;
|
||||
}
|
||||
for kw_arg in kw_args.iter() {
|
||||
if let Err(mut es) = self.substitute_kw_arg(
|
||||
&callee,
|
||||
|
@ -1032,7 +1046,7 @@ impl Context {
|
|||
}
|
||||
nth += 1;
|
||||
}
|
||||
let missing_len = non_default_params_len - pos_args.len() - passed_params.len();
|
||||
let missing_len = params_len - passed_params.len();
|
||||
if missing_len > 0 {
|
||||
let missing_params = subr
|
||||
.non_default_params
|
||||
|
@ -1040,7 +1054,7 @@ impl Context {
|
|||
.rev()
|
||||
.take(missing_len)
|
||||
.rev()
|
||||
.map(|pt| pt.name().cloned().unwrap_or(Str::ever("")))
|
||||
.map(|pt| pt.name().cloned().unwrap_or(Str::ever("_")))
|
||||
.filter(|pt| !passed_params.contains(pt))
|
||||
.collect();
|
||||
return Err(TyCheckErrors::from(TyCheckError::args_missing_error(
|
||||
|
@ -1173,6 +1187,20 @@ impl Context {
|
|||
) -> TyCheckResult<()> {
|
||||
let arg_t = arg.ref_t();
|
||||
let param_t = ¶m.typ();
|
||||
if let Some(name) = param.name() {
|
||||
if passed_params.contains(name) {
|
||||
return Err(TyCheckErrors::from(TyCheckError::multiple_args_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
callee.loc(),
|
||||
&callee.to_string(),
|
||||
self.caused_by(),
|
||||
name,
|
||||
)));
|
||||
} else {
|
||||
passed_params.insert(name.clone());
|
||||
}
|
||||
}
|
||||
self.sub_unify(arg_t, param_t, arg.loc(), param.name())
|
||||
.map_err(|errs| {
|
||||
log!(err "semi-unification failed with {callee}\n{arg_t} !<: {param_t}");
|
||||
|
@ -1201,20 +1229,6 @@ impl Context {
|
|||
.collect(),
|
||||
)
|
||||
})?;
|
||||
if let Some(name) = param.name() {
|
||||
if passed_params.contains(name) {
|
||||
return Err(TyCheckErrors::from(TyCheckError::multiple_args_error(
|
||||
self.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
callee.loc(),
|
||||
&callee.to_string(),
|
||||
self.caused_by(),
|
||||
name,
|
||||
)));
|
||||
} else {
|
||||
passed_params.insert(name.clone());
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -1287,6 +1301,7 @@ impl Context {
|
|||
.chain(subr_ty.default_params.iter())
|
||||
.find(|pt| pt.name().unwrap() == kw_name)
|
||||
{
|
||||
passed_params.insert(kw_name.clone());
|
||||
self.sub_unify(arg_t, pt.typ(), arg.loc(), Some(kw_name))
|
||||
.map_err(|errs| {
|
||||
log!(err "semi-unification failed with {callee}\n{arg_t} !<: {}", pt.typ());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue