mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-28 04:09:05 +00:00
fix: ownership checker bug
This commit is contained in:
parent
94df64d696
commit
c34e013658
5 changed files with 65 additions and 52 deletions
|
@ -389,7 +389,7 @@ impl Context {
|
|||
)
|
||||
.quantify();
|
||||
let t_staticmethod = nd_func(vec![kw(KW_FUNC, F.clone())], None, F.clone()).quantify();
|
||||
let t_str = nd_func(vec![kw(KW_OBJECT, Obj)], None, Str)
|
||||
let t_str = nd_func(vec![kw(KW_OBJECT, ref_(Obj))], None, Str)
|
||||
& no_var_func(
|
||||
vec![kw(KW_BYTES_OR_BUFFER, mono(BYTES)), kw(KW_ENCODING, Str)],
|
||||
vec![kw(KW_ERRORS, Str)],
|
||||
|
|
|
@ -580,7 +580,7 @@ impl Context {
|
|||
for arg_t in branch_ts.iter().skip(1) {
|
||||
return_t = self.union(&return_t, arg_t.typ().return_t().unwrap_or(&Type::Never));
|
||||
}
|
||||
let param_ty = ParamTy::Pos(match_target_expr_t.clone());
|
||||
let param_ty = ParamTy::Pos(match_target_expr_t.clone().into_ref());
|
||||
let param_ts = [vec![param_ty], branch_ts.to_vec()].concat();
|
||||
let t = if kind.is_func() {
|
||||
func(param_ts, None, vec![], None, return_t)
|
||||
|
|
|
@ -165,63 +165,63 @@ impl OwnershipChecker {
|
|||
args_owns.non_defaults.len()
|
||||
};
|
||||
let defaults_len = args_owns.defaults.len();
|
||||
if call.args.pos_args.len() > non_defaults_len {
|
||||
let (non_default_args, var_args) =
|
||||
call.args.pos_args.split_at(non_defaults_len);
|
||||
for (nd_arg, (_, ownership)) in
|
||||
non_default_args.iter().zip(args_owns.non_defaults.iter())
|
||||
{
|
||||
self.check_expr(&nd_arg.expr, *ownership, false);
|
||||
let (non_default_args, var_args) = call
|
||||
.args
|
||||
.pos_args
|
||||
.split_at(usize::min(non_defaults_len, call.args.pos_args.len()));
|
||||
for (nd_arg, (_, ownership)) in
|
||||
non_default_args.iter().zip(args_owns.non_defaults.iter())
|
||||
{
|
||||
self.check_expr(&nd_arg.expr, *ownership, false);
|
||||
}
|
||||
if let Some((_, ownership)) = args_owns.var_params.as_ref() {
|
||||
for var_arg in var_args.iter() {
|
||||
self.check_expr(&var_arg.expr, *ownership, false);
|
||||
}
|
||||
if let Some((_, ownership)) = args_owns.var_params.as_ref() {
|
||||
for var_arg in var_args.iter() {
|
||||
self.check_expr(&var_arg.expr, *ownership, false);
|
||||
}
|
||||
} else {
|
||||
let kw_args = var_args;
|
||||
for (arg, (_, ownership)) in kw_args.iter().zip(args_owns.defaults.iter()) {
|
||||
self.check_expr(&arg.expr, *ownership, false);
|
||||
}
|
||||
} else {
|
||||
let kw_args = var_args;
|
||||
for (arg, (_, ownership)) in kw_args.iter().zip(args_owns.defaults.iter()) {
|
||||
self.check_expr(&arg.expr, *ownership, false);
|
||||
}
|
||||
}
|
||||
if call.args.kw_args.len() > defaults_len {
|
||||
let (default_args, kw_var_args) = call.args.kw_args.split_at(defaults_len);
|
||||
for kw_arg in default_args.iter() {
|
||||
if let Some((_, ownership)) = args_owns
|
||||
.defaults
|
||||
.iter()
|
||||
.find(|(k, _)| k == kw_arg.keyword.inspect())
|
||||
{
|
||||
self.check_expr(&kw_arg.expr, *ownership, false);
|
||||
} else if let Some((_, ownership)) = args_owns
|
||||
.non_defaults
|
||||
.iter()
|
||||
.find(|(k, _)| k.as_ref() == Some(kw_arg.keyword.inspect()))
|
||||
{
|
||||
self.check_expr(&kw_arg.expr, *ownership, false);
|
||||
} else {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
if let Some((_, ownership)) = args_owns.kw_var_params.as_ref() {
|
||||
for var_arg in kw_var_args.iter() {
|
||||
self.check_expr(&var_arg.expr, *ownership, false);
|
||||
}
|
||||
let (default_args, kw_var_args) = call
|
||||
.args
|
||||
.kw_args
|
||||
.split_at(usize::min(defaults_len, call.args.kw_args.len()));
|
||||
for kw_arg in default_args.iter() {
|
||||
if let Some((_, ownership)) = args_owns
|
||||
.defaults
|
||||
.iter()
|
||||
.find(|(k, _)| k == kw_arg.keyword.inspect())
|
||||
{
|
||||
self.check_expr(&kw_arg.expr, *ownership, false);
|
||||
} else if let Some((_, ownership)) = args_owns
|
||||
.non_defaults
|
||||
.iter()
|
||||
.find(|(k, _)| k.as_ref() == Some(kw_arg.keyword.inspect()))
|
||||
{
|
||||
self.check_expr(&kw_arg.expr, *ownership, false);
|
||||
} else {
|
||||
let kw_args = kw_var_args;
|
||||
for (arg, (_, ownership)) in kw_args.iter().zip(args_owns.defaults.iter()) {
|
||||
self.check_expr(&arg.expr, *ownership, false);
|
||||
}
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
if let Some((_, ownership)) = args_owns.kw_var_params.as_ref() {
|
||||
for var_arg in kw_var_args.iter() {
|
||||
self.check_expr(&var_arg.expr, *ownership, false);
|
||||
}
|
||||
} else {
|
||||
let kw_args = kw_var_args;
|
||||
for (arg, (_, ownership)) in kw_args.iter().zip(args_owns.defaults.iter()) {
|
||||
self.check_expr(&arg.expr, *ownership, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO: referenced
|
||||
Expr::BinOp(binop) => {
|
||||
self.check_expr(&binop.lhs, ownership, false);
|
||||
self.check_expr(&binop.rhs, ownership, false);
|
||||
self.check_expr(&binop.lhs, Ownership::Ref, false);
|
||||
self.check_expr(&binop.rhs, Ownership::Ref, false);
|
||||
}
|
||||
Expr::UnaryOp(unary) => {
|
||||
self.check_expr(&unary.expr, ownership, false);
|
||||
self.check_expr(&unary.expr, Ownership::Ref, false);
|
||||
}
|
||||
Expr::List(list) => match list {
|
||||
List::Normal(lis) => {
|
||||
|
|
|
@ -882,7 +882,14 @@ impl SubrType {
|
|||
let ownership = match nd_param.typ() {
|
||||
Type::Ref(_) => Ownership::Ref,
|
||||
Type::RefMut { .. } => Ownership::RefMut,
|
||||
_ => Ownership::Owned,
|
||||
other => {
|
||||
if other.is_mut_type() {
|
||||
Ownership::Owned
|
||||
} else {
|
||||
// e.g. passed `Nat!`, but coerced to `Nat`
|
||||
Ownership::Ref
|
||||
}
|
||||
}
|
||||
};
|
||||
nd_args.push((nd_param.name().cloned(), ownership));
|
||||
}
|
||||
|
@ -895,7 +902,13 @@ impl SubrType {
|
|||
let ownership = match d_param.typ() {
|
||||
Type::Ref(_) => Ownership::Ref,
|
||||
Type::RefMut { .. } => Ownership::RefMut,
|
||||
_ => Ownership::Owned,
|
||||
other => {
|
||||
if other.is_mut_type() {
|
||||
Ownership::Owned
|
||||
} else {
|
||||
Ownership::Ref
|
||||
}
|
||||
}
|
||||
};
|
||||
d_args.push((d_param.name().unwrap().clone(), ownership));
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ get_badge! file_path =
|
|||
do!:
|
||||
"File not found"
|
||||
|
||||
get_doc_en_file_paths! relative_dir_path, relative_file_paths_result := [] =
|
||||
get_doc_en_file_paths! relative_dir_path, relative_file_paths_result: List(Str) := [] =
|
||||
dir_path = mylib.path_join(cwd, relative_dir_path)
|
||||
dir_list = sorted os.listdir! dir_path
|
||||
relative_file_paths = ![]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue