fix: ownership checker bug

This commit is contained in:
Shunsuke Shibayama 2024-12-25 16:26:53 +09:00
parent 94df64d696
commit c34e013658
5 changed files with 65 additions and 52 deletions

View file

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

View file

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

View file

@ -165,9 +165,10 @@ 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
.split_at(usize::min(non_defaults_len, call.args.pos_args.len()));
for (nd_arg, (_, ownership)) in for (nd_arg, (_, ownership)) in
non_default_args.iter().zip(args_owns.non_defaults.iter()) non_default_args.iter().zip(args_owns.non_defaults.iter())
{ {
@ -183,9 +184,10 @@ impl OwnershipChecker {
self.check_expr(&arg.expr, *ownership, false); self.check_expr(&arg.expr, *ownership, false);
} }
} }
} let (default_args, kw_var_args) = call
if call.args.kw_args.len() > defaults_len { .args
let (default_args, kw_var_args) = call.args.kw_args.split_at(defaults_len); .kw_args
.split_at(usize::min(defaults_len, call.args.kw_args.len()));
for kw_arg in default_args.iter() { for kw_arg in default_args.iter() {
if let Some((_, ownership)) = args_owns if let Some((_, ownership)) = args_owns
.defaults .defaults
@ -214,14 +216,12 @@ impl OwnershipChecker {
} }
} }
} }
}
// 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) => {

View file

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

View file

@ -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 = ![]