mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-28 12:14:43 +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();
|
.quantify();
|
||||||
let t_staticmethod = nd_func(vec![kw(KW_FUNC, F.clone())], None, F.clone()).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(
|
& no_var_func(
|
||||||
vec![kw(KW_BYTES_OR_BUFFER, mono(BYTES)), kw(KW_ENCODING, Str)],
|
vec![kw(KW_BYTES_OR_BUFFER, mono(BYTES)), kw(KW_ENCODING, Str)],
|
||||||
vec![kw(KW_ERRORS, Str)],
|
vec![kw(KW_ERRORS, Str)],
|
||||||
|
|
|
@ -580,7 +580,7 @@ impl Context {
|
||||||
for arg_t in branch_ts.iter().skip(1) {
|
for arg_t in branch_ts.iter().skip(1) {
|
||||||
return_t = self.union(&return_t, arg_t.typ().return_t().unwrap_or(&Type::Never));
|
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 param_ts = [vec![param_ty], branch_ts.to_vec()].concat();
|
||||||
let t = if kind.is_func() {
|
let t = if kind.is_func() {
|
||||||
func(param_ts, None, vec![], None, return_t)
|
func(param_ts, None, vec![], None, return_t)
|
||||||
|
|
|
@ -165,63 +165,63 @@ impl OwnershipChecker {
|
||||||
args_owns.non_defaults.len()
|
args_owns.non_defaults.len()
|
||||||
};
|
};
|
||||||
let defaults_len = args_owns.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
|
||||||
let (non_default_args, var_args) =
|
.args
|
||||||
call.args.pos_args.split_at(non_defaults_len);
|
.pos_args
|
||||||
for (nd_arg, (_, ownership)) in
|
.split_at(usize::min(non_defaults_len, call.args.pos_args.len()));
|
||||||
non_default_args.iter().zip(args_owns.non_defaults.iter())
|
for (nd_arg, (_, ownership)) in
|
||||||
{
|
non_default_args.iter().zip(args_owns.non_defaults.iter())
|
||||||
self.check_expr(&nd_arg.expr, *ownership, false);
|
{
|
||||||
|
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() {
|
} else {
|
||||||
for var_arg in var_args.iter() {
|
let kw_args = var_args;
|
||||||
self.check_expr(&var_arg.expr, *ownership, false);
|
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
|
||||||
let (default_args, kw_var_args) = call.args.kw_args.split_at(defaults_len);
|
.args
|
||||||
for kw_arg in default_args.iter() {
|
.kw_args
|
||||||
if let Some((_, ownership)) = args_owns
|
.split_at(usize::min(defaults_len, call.args.kw_args.len()));
|
||||||
.defaults
|
for kw_arg in default_args.iter() {
|
||||||
.iter()
|
if let Some((_, ownership)) = args_owns
|
||||||
.find(|(k, _)| k == kw_arg.keyword.inspect())
|
.defaults
|
||||||
{
|
.iter()
|
||||||
self.check_expr(&kw_arg.expr, *ownership, false);
|
.find(|(k, _)| k == kw_arg.keyword.inspect())
|
||||||
} else if let Some((_, ownership)) = args_owns
|
{
|
||||||
.non_defaults
|
self.check_expr(&kw_arg.expr, *ownership, false);
|
||||||
.iter()
|
} else if let Some((_, ownership)) = args_owns
|
||||||
.find(|(k, _)| k.as_ref() == Some(kw_arg.keyword.inspect()))
|
.non_defaults
|
||||||
{
|
.iter()
|
||||||
self.check_expr(&kw_arg.expr, *ownership, false);
|
.find(|(k, _)| k.as_ref() == Some(kw_arg.keyword.inspect()))
|
||||||
} else {
|
{
|
||||||
todo!()
|
self.check_expr(&kw_arg.expr, *ownership, false);
|
||||||
}
|
|
||||||
}
|
|
||||||
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 {
|
} else {
|
||||||
let kw_args = kw_var_args;
|
todo!()
|
||||||
for (arg, (_, ownership)) in kw_args.iter().zip(args_owns.defaults.iter()) {
|
}
|
||||||
self.check_expr(&arg.expr, *ownership, false);
|
}
|
||||||
}
|
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) => {
|
Expr::BinOp(binop) => {
|
||||||
self.check_expr(&binop.lhs, ownership, false);
|
self.check_expr(&binop.lhs, Ownership::Ref, false);
|
||||||
self.check_expr(&binop.rhs, ownership, false);
|
self.check_expr(&binop.rhs, Ownership::Ref, false);
|
||||||
}
|
}
|
||||||
Expr::UnaryOp(unary) => {
|
Expr::UnaryOp(unary) => {
|
||||||
self.check_expr(&unary.expr, ownership, false);
|
self.check_expr(&unary.expr, Ownership::Ref, false);
|
||||||
}
|
}
|
||||||
Expr::List(list) => match list {
|
Expr::List(list) => match list {
|
||||||
List::Normal(lis) => {
|
List::Normal(lis) => {
|
||||||
|
|
|
@ -882,7 +882,14 @@ impl SubrType {
|
||||||
let ownership = match nd_param.typ() {
|
let ownership = match nd_param.typ() {
|
||||||
Type::Ref(_) => Ownership::Ref,
|
Type::Ref(_) => Ownership::Ref,
|
||||||
Type::RefMut { .. } => Ownership::RefMut,
|
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));
|
nd_args.push((nd_param.name().cloned(), ownership));
|
||||||
}
|
}
|
||||||
|
@ -895,7 +902,13 @@ impl SubrType {
|
||||||
let ownership = match d_param.typ() {
|
let ownership = match d_param.typ() {
|
||||||
Type::Ref(_) => Ownership::Ref,
|
Type::Ref(_) => Ownership::Ref,
|
||||||
Type::RefMut { .. } => Ownership::RefMut,
|
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));
|
d_args.push((d_param.name().unwrap().clone(), ownership));
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ get_badge! file_path =
|
||||||
do!:
|
do!:
|
||||||
"File not found"
|
"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_path = mylib.path_join(cwd, relative_dir_path)
|
||||||
dir_list = sorted os.listdir! dir_path
|
dir_list = sorted os.listdir! dir_path
|
||||||
relative_file_paths = ![]
|
relative_file_paths = ![]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue