mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-30 12:51:10 +00:00
commit
38d69e6b96
6 changed files with 201 additions and 92 deletions
|
@ -1926,9 +1926,10 @@ impl PyCodeGenerator {
|
||||||
self.emit_call_local(ident, call.args)
|
self.emit_call_local(ident, call.args)
|
||||||
}
|
}
|
||||||
other => {
|
other => {
|
||||||
|
let is_py_api = other.is_py_api();
|
||||||
self.emit_push_null();
|
self.emit_push_null();
|
||||||
self.emit_expr(other);
|
self.emit_expr(other);
|
||||||
self.emit_args_311(call.args, Name);
|
self.emit_args_311(call.args, Name, is_py_api);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1952,11 +1953,12 @@ impl PyCodeGenerator {
|
||||||
Some(8) => self.emit_with_instr_308(args),
|
Some(8) => self.emit_with_instr_308(args),
|
||||||
_ => todo!(),
|
_ => todo!(),
|
||||||
},
|
},
|
||||||
// "pyimport" | "py" |
|
// "pyimport" | "py" are here
|
||||||
_ => {
|
_ => {
|
||||||
|
let is_py_api = local.is_py_api();
|
||||||
self.emit_push_null();
|
self.emit_push_null();
|
||||||
self.emit_load_name_instr(local);
|
self.emit_load_name_instr(local);
|
||||||
self.emit_args_311(args, Name);
|
self.emit_args_311(args, Name, is_py_api);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1973,9 +1975,10 @@ impl PyCodeGenerator {
|
||||||
} else if let Some(func_name) = fake_method_to_func(&class, method_name.inspect()) {
|
} else if let Some(func_name) = fake_method_to_func(&class, method_name.inspect()) {
|
||||||
return self.emit_call_fake_method(obj, func_name, method_name, args);
|
return self.emit_call_fake_method(obj, func_name, method_name, args);
|
||||||
}
|
}
|
||||||
|
let is_py_api = obj.is_py_api();
|
||||||
self.emit_expr(obj);
|
self.emit_expr(obj);
|
||||||
self.emit_load_method_instr(method_name);
|
self.emit_load_method_instr(method_name);
|
||||||
self.emit_args_311(args, Method);
|
self.emit_args_311(args, Method, is_py_api);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_var_args_311(&mut self, pos_len: usize, var_args: &PosArg) {
|
fn emit_var_args_311(&mut self, pos_len: usize, var_args: &PosArg) {
|
||||||
|
@ -2004,7 +2007,7 @@ impl PyCodeGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_args_311(&mut self, mut args: Args, kind: AccessKind) {
|
fn emit_args_311(&mut self, mut args: Args, kind: AccessKind, is_py_api: bool) {
|
||||||
let argc = args.len();
|
let argc = args.len();
|
||||||
let pos_len = args.pos_args.len();
|
let pos_len = args.pos_args.len();
|
||||||
let mut kws = Vec::with_capacity(args.kw_len());
|
let mut kws = Vec::with_capacity(args.kw_len());
|
||||||
|
@ -2019,7 +2022,12 @@ impl PyCodeGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
while let Some(arg) = args.try_remove_kw(0) {
|
while let Some(arg) = args.try_remove_kw(0) {
|
||||||
kws.push(ValueObj::Str(arg.keyword.content.clone()));
|
let kw = if is_py_api {
|
||||||
|
arg.keyword.content
|
||||||
|
} else {
|
||||||
|
Str::from(format!("::{}", arg.keyword.content))
|
||||||
|
};
|
||||||
|
kws.push(ValueObj::Str(kw));
|
||||||
self.emit_expr(arg.expr);
|
self.emit_expr(arg.expr);
|
||||||
}
|
}
|
||||||
let kwsc = if !kws.is_empty() {
|
let kwsc = if !kws.is_empty() {
|
||||||
|
@ -2095,7 +2103,7 @@ impl PyCodeGenerator {
|
||||||
self.emit_push_null();
|
self.emit_push_null();
|
||||||
self.emit_load_name_instr(method_name);
|
self.emit_load_name_instr(method_name);
|
||||||
args.insert_pos(0, PosArg::new(obj));
|
args.insert_pos(0, PosArg::new(obj));
|
||||||
self.emit_args_311(args, Name);
|
self.emit_args_311(args, Name, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// assert takes 1 or 2 arguments (0: cond, 1: message)
|
// assert takes 1 or 2 arguments (0: cond, 1: message)
|
||||||
|
|
|
@ -931,38 +931,25 @@ impl Context {
|
||||||
if (params_len < pos_args.len() || params_len < pos_args.len() + kw_args.len())
|
if (params_len < pos_args.len() || params_len < pos_args.len() + kw_args.len())
|
||||||
&& subr.var_params.is_none()
|
&& subr.var_params.is_none()
|
||||||
{
|
{
|
||||||
return Err(TyCheckErrors::from(TyCheckError::too_many_args_error(
|
return Err(self.gen_too_many_args_error(&callee, subr, pos_args, kw_args));
|
||||||
self.cfg.input.clone(),
|
|
||||||
line!() as usize,
|
|
||||||
callee.loc(),
|
|
||||||
&callee.to_string(),
|
|
||||||
self.caused_by(),
|
|
||||||
params_len,
|
|
||||||
pos_args.len(),
|
|
||||||
kw_args.len(),
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
let mut passed_params = set! {};
|
let mut passed_params = set! {};
|
||||||
let non_default_params_len = if attr_name.is_some() && is_method {
|
let non_default_params = if is_method {
|
||||||
subr.non_default_params.len() - 1
|
let mut non_default_params = subr.non_default_params.iter();
|
||||||
|
let self_pt = non_default_params.next().unwrap();
|
||||||
|
if let Err(mut es) =
|
||||||
|
self.sub_unify(obj.ref_t(), self_pt.typ(), obj.loc(), self_pt.name())
|
||||||
|
{
|
||||||
|
errs.append(&mut es);
|
||||||
|
}
|
||||||
|
non_default_params
|
||||||
} else {
|
} else {
|
||||||
subr.non_default_params.len()
|
subr.non_default_params.iter()
|
||||||
};
|
};
|
||||||
|
let non_default_params_len = non_default_params.len();
|
||||||
let mut nth = 1;
|
let mut nth = 1;
|
||||||
if pos_args.len() >= non_default_params_len {
|
if pos_args.len() >= non_default_params_len {
|
||||||
let (non_default_args, var_args) = pos_args.split_at(non_default_params_len);
|
let (non_default_args, var_args) = pos_args.split_at(non_default_params_len);
|
||||||
let non_default_params = if is_method {
|
|
||||||
let mut non_default_params = subr.non_default_params.iter();
|
|
||||||
let self_pt = non_default_params.next().unwrap();
|
|
||||||
if let Err(mut es) =
|
|
||||||
self.sub_unify(obj.ref_t(), self_pt.typ(), obj.loc(), self_pt.name())
|
|
||||||
{
|
|
||||||
errs.append(&mut es);
|
|
||||||
}
|
|
||||||
non_default_params
|
|
||||||
} else {
|
|
||||||
subr.non_default_params.iter()
|
|
||||||
};
|
|
||||||
for (nd_arg, nd_param) in non_default_args.iter().zip(non_default_params) {
|
for (nd_arg, nd_param) in non_default_args.iter().zip(non_default_params) {
|
||||||
if let Err(mut es) = self.substitute_pos_arg(
|
if let Err(mut es) = self.substitute_pos_arg(
|
||||||
&callee,
|
&callee,
|
||||||
|
@ -1010,7 +997,7 @@ impl Context {
|
||||||
attr_name,
|
attr_name,
|
||||||
kw_arg,
|
kw_arg,
|
||||||
nth,
|
nth,
|
||||||
&subr.default_params,
|
subr,
|
||||||
&mut passed_params,
|
&mut passed_params,
|
||||||
) {
|
) {
|
||||||
errs.append(&mut es);
|
errs.append(&mut es);
|
||||||
|
@ -1031,24 +1018,41 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let missing_len = subr.non_default_params.len() - pos_args.len();
|
// pos_args.len() < non_default_params_len
|
||||||
let missing_params = subr
|
for kw_arg in kw_args.iter() {
|
||||||
.non_default_params
|
if let Err(mut es) = self.substitute_kw_arg(
|
||||||
.iter()
|
&callee,
|
||||||
.rev()
|
attr_name,
|
||||||
.take(missing_len)
|
kw_arg,
|
||||||
.rev()
|
nth,
|
||||||
.map(|pt| pt.name().cloned().unwrap_or(Str::ever("")))
|
subr,
|
||||||
.collect();
|
&mut passed_params,
|
||||||
return Err(TyCheckErrors::from(TyCheckError::args_missing_error(
|
) {
|
||||||
self.cfg.input.clone(),
|
errs.append(&mut es);
|
||||||
line!() as usize,
|
}
|
||||||
callee.loc(),
|
nth += 1;
|
||||||
&callee.to_string(),
|
}
|
||||||
self.caused_by(),
|
let missing_len = non_default_params_len - pos_args.len() - passed_params.len();
|
||||||
missing_len,
|
if missing_len > 0 {
|
||||||
missing_params,
|
let missing_params = subr
|
||||||
)));
|
.non_default_params
|
||||||
|
.iter()
|
||||||
|
.rev()
|
||||||
|
.take(missing_len)
|
||||||
|
.rev()
|
||||||
|
.map(|pt| pt.name().cloned().unwrap_or(Str::ever("")))
|
||||||
|
.filter(|pt| !passed_params.contains(pt))
|
||||||
|
.collect();
|
||||||
|
return Err(TyCheckErrors::from(TyCheckError::args_missing_error(
|
||||||
|
self.cfg.input.clone(),
|
||||||
|
line!() as usize,
|
||||||
|
callee.loc(),
|
||||||
|
&callee.to_string(),
|
||||||
|
self.caused_by(),
|
||||||
|
missing_len,
|
||||||
|
missing_params,
|
||||||
|
)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if errs.is_empty() {
|
if errs.is_empty() {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -1088,6 +1092,76 @@ impl Context {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn gen_too_many_args_error(
|
||||||
|
&self,
|
||||||
|
callee: &hir::Expr,
|
||||||
|
subr_ty: &SubrType,
|
||||||
|
pos_args: &[hir::PosArg],
|
||||||
|
kw_args: &[hir::KwArg],
|
||||||
|
) -> TyCheckErrors {
|
||||||
|
let mut unknown_args = vec![];
|
||||||
|
let mut passed_args: Vec<&hir::KwArg> = vec![];
|
||||||
|
let mut duplicated_args = vec![];
|
||||||
|
for kw_arg in kw_args.iter() {
|
||||||
|
if subr_ty
|
||||||
|
.non_default_params
|
||||||
|
.iter()
|
||||||
|
.all(|pt| pt.name() != Some(kw_arg.keyword.inspect()))
|
||||||
|
&& subr_ty
|
||||||
|
.var_params
|
||||||
|
.as_ref()
|
||||||
|
.map(|pt| pt.name() != Some(kw_arg.keyword.inspect()))
|
||||||
|
.unwrap_or(true)
|
||||||
|
&& subr_ty
|
||||||
|
.default_params
|
||||||
|
.iter()
|
||||||
|
.all(|pt| pt.name() != Some(kw_arg.keyword.inspect()))
|
||||||
|
{
|
||||||
|
unknown_args.push(kw_arg);
|
||||||
|
}
|
||||||
|
if passed_args.iter().any(|a| a.keyword == kw_arg.keyword) {
|
||||||
|
duplicated_args.push(kw_arg);
|
||||||
|
} else {
|
||||||
|
passed_args.push(kw_arg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if unknown_args.is_empty() && duplicated_args.is_empty() {
|
||||||
|
let params_len = subr_ty.non_default_params.len() + subr_ty.default_params.len();
|
||||||
|
TyCheckErrors::from(TyCheckError::too_many_args_error(
|
||||||
|
self.cfg.input.clone(),
|
||||||
|
line!() as usize,
|
||||||
|
callee.loc(),
|
||||||
|
&callee.to_string(),
|
||||||
|
self.caused_by(),
|
||||||
|
params_len,
|
||||||
|
pos_args.len(),
|
||||||
|
kw_args.len(),
|
||||||
|
))
|
||||||
|
} else {
|
||||||
|
let unknown_arg_errors = unknown_args.into_iter().map(|arg| {
|
||||||
|
TyCheckError::unexpected_kw_arg_error(
|
||||||
|
self.cfg.input.clone(),
|
||||||
|
line!() as usize,
|
||||||
|
arg.loc(),
|
||||||
|
&callee.to_string(),
|
||||||
|
self.caused_by(),
|
||||||
|
arg.keyword.inspect(),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
let duplicated_arg_errors = duplicated_args.into_iter().map(|arg| {
|
||||||
|
TyCheckError::multiple_args_error(
|
||||||
|
self.cfg.input.clone(),
|
||||||
|
line!() as usize,
|
||||||
|
arg.loc(),
|
||||||
|
&callee.to_string(),
|
||||||
|
self.caused_by(),
|
||||||
|
arg.keyword.inspect(),
|
||||||
|
)
|
||||||
|
});
|
||||||
|
unknown_arg_errors.chain(duplicated_arg_errors).collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn substitute_pos_arg(
|
fn substitute_pos_arg(
|
||||||
&self,
|
&self,
|
||||||
callee: &hir::Expr,
|
callee: &hir::Expr,
|
||||||
|
@ -1190,7 +1264,7 @@ impl Context {
|
||||||
attr_name: &Option<Identifier>,
|
attr_name: &Option<Identifier>,
|
||||||
arg: &hir::KwArg,
|
arg: &hir::KwArg,
|
||||||
nth: usize,
|
nth: usize,
|
||||||
default_params: &[ParamTy],
|
subr_ty: &SubrType,
|
||||||
passed_params: &mut Set<Str>,
|
passed_params: &mut Set<Str>,
|
||||||
) -> TyCheckResult<()> {
|
) -> TyCheckResult<()> {
|
||||||
let arg_t = arg.expr.ref_t();
|
let arg_t = arg.expr.ref_t();
|
||||||
|
@ -1207,8 +1281,10 @@ impl Context {
|
||||||
} else {
|
} else {
|
||||||
passed_params.insert(kw_name.clone());
|
passed_params.insert(kw_name.clone());
|
||||||
}
|
}
|
||||||
if let Some(pt) = default_params
|
if let Some(pt) = subr_ty
|
||||||
|
.non_default_params
|
||||||
.iter()
|
.iter()
|
||||||
|
.chain(subr_ty.default_params.iter())
|
||||||
.find(|pt| pt.name().unwrap() == kw_name)
|
.find(|pt| pt.name().unwrap() == kw_name)
|
||||||
{
|
{
|
||||||
self.sub_unify(arg_t, pt.typ(), arg.loc(), Some(kw_name))
|
self.sub_unify(arg_t, pt.typ(), arg.loc(), Some(kw_name))
|
||||||
|
@ -1263,7 +1339,6 @@ impl Context {
|
||||||
) -> TyCheckResult<VarInfo> {
|
) -> TyCheckResult<VarInfo> {
|
||||||
if let hir::Expr::Accessor(hir::Accessor::Ident(local)) = obj {
|
if let hir::Expr::Accessor(hir::Accessor::Ident(local)) = obj {
|
||||||
if local.vis().is_private() {
|
if local.vis().is_private() {
|
||||||
#[allow(clippy::single_match)]
|
|
||||||
match &local.inspect()[..] {
|
match &local.inspect()[..] {
|
||||||
"match" => {
|
"match" => {
|
||||||
return self.get_match_call_t(SubrKind::Func, pos_args, kw_args);
|
return self.get_match_call_t(SubrKind::Func, pos_args, kw_args);
|
||||||
|
@ -1271,20 +1346,6 @@ impl Context {
|
||||||
"match!" => {
|
"match!" => {
|
||||||
return self.get_match_call_t(SubrKind::Proc, pos_args, kw_args);
|
return self.get_match_call_t(SubrKind::Proc, pos_args, kw_args);
|
||||||
}
|
}
|
||||||
/*"import" | "pyimport" | "py" => {
|
|
||||||
return self.get_import_call_t(pos_args, kw_args);
|
|
||||||
}*/
|
|
||||||
// handle assert casting
|
|
||||||
/*"assert" => {
|
|
||||||
if let Some(arg) = pos_args.first() {
|
|
||||||
match &arg.expr {
|
|
||||||
hir::Expr::BinOp(bin) if bin.op.is(TokenKind::InOp) && bin.rhs.ref_t() == &Type => {
|
|
||||||
let t = self.eval_const_expr(bin.lhs.as_ref(), None)?.as_type().unwrap();
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},*/
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -422,6 +422,10 @@ impl Identifier {
|
||||||
Self::new(dot, name, None, VarInfo::const_default())
|
Self::new(dot, name, None, VarInfo::const_default())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_py_api(&self) -> bool {
|
||||||
|
self.vi.py_name.is_some()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_const(&self) -> bool {
|
pub fn is_const(&self) -> bool {
|
||||||
self.name.is_const()
|
self.name.is_const()
|
||||||
}
|
}
|
||||||
|
@ -539,6 +543,13 @@ impl Accessor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_py_api(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Self::Ident(ident) => ident.is_py_api(),
|
||||||
|
Self::Attr(attr) => attr.ident.is_py_api(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 参照するオブジェクト自体が持っている固有の名前(クラス、モジュールなど)
|
// 参照するオブジェクト自体が持っている固有の名前(クラス、モジュールなど)
|
||||||
pub fn qual_name(&self) -> Option<&str> {
|
pub fn qual_name(&self) -> Option<&str> {
|
||||||
match self {
|
match self {
|
||||||
|
@ -1919,6 +1930,13 @@ impl Expr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_py_api(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
Expr::Accessor(acc) => acc.is_py_api(),
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn is_type_asc(&self) -> bool {
|
pub fn is_type_asc(&self) -> bool {
|
||||||
matches!(self, Expr::TypeAsc(_))
|
matches!(self, Expr::TypeAsc(_))
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,20 +136,23 @@ impl OwnershipChecker {
|
||||||
} else {
|
} else {
|
||||||
args_owns.non_defaults.len()
|
args_owns.non_defaults.len()
|
||||||
};
|
};
|
||||||
let (non_default_args, var_args) = call.args.pos_args.split_at(non_defaults_len);
|
if call.args.pos_args.len() > non_defaults_len {
|
||||||
for (nd_arg, ownership) in
|
let (non_default_args, var_args) =
|
||||||
non_default_args.iter().zip(args_owns.non_defaults.iter())
|
call.args.pos_args.split_at(non_defaults_len);
|
||||||
{
|
for (nd_arg, (_, ownership)) in
|
||||||
self.check_expr(&nd_arg.expr, *ownership, false);
|
non_default_args.iter().zip(args_owns.non_defaults.iter())
|
||||||
}
|
{
|
||||||
if let Some(ownership) = args_owns.var_params.as_ref() {
|
self.check_expr(&nd_arg.expr, *ownership, false);
|
||||||
for var_arg in var_args.iter() {
|
|
||||||
self.check_expr(&var_arg.expr, *ownership, false);
|
|
||||||
}
|
}
|
||||||
} else {
|
if let Some((_, ownership)) = args_owns.var_params.as_ref() {
|
||||||
let kw_args = var_args;
|
for var_arg in var_args.iter() {
|
||||||
for (arg, (_, ownership)) in kw_args.iter().zip(args_owns.defaults.iter()) {
|
self.check_expr(&var_arg.expr, *ownership, false);
|
||||||
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for kw_arg in call.args.kw_args.iter() {
|
for kw_arg in call.args.kw_args.iter() {
|
||||||
|
@ -159,6 +162,12 @@ impl OwnershipChecker {
|
||||||
.find(|(k, _)| k == kw_arg.keyword.inspect())
|
.find(|(k, _)| k == kw_arg.keyword.inspect())
|
||||||
{
|
{
|
||||||
self.check_expr(&kw_arg.expr, *ownership, false);
|
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 {
|
} else {
|
||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
|
@ -431,6 +431,7 @@ impl ScriptGenerator {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn transpile_simple_call(&mut self, mut call: Call) -> String {
|
fn transpile_simple_call(&mut self, mut call: Call) -> String {
|
||||||
|
let is_py_api = call.obj.is_py_api();
|
||||||
let mut code = format!("({})", self.transpile_expr(*call.obj));
|
let mut code = format!("({})", self.transpile_expr(*call.obj));
|
||||||
if let Some(attr) = call.attr_name {
|
if let Some(attr) = call.attr_name {
|
||||||
code += &format!(".{}", Self::transpile_ident(attr));
|
code += &format!(".{}", Self::transpile_ident(attr));
|
||||||
|
@ -441,7 +442,12 @@ impl ScriptGenerator {
|
||||||
code.push(',');
|
code.push(',');
|
||||||
}
|
}
|
||||||
while let Some(arg) = call.args.try_remove_kw(0) {
|
while let Some(arg) = call.args.try_remove_kw(0) {
|
||||||
code += &format!("{}={},", arg.keyword, self.transpile_expr(arg.expr));
|
let escape = if is_py_api { "" } else { "__" };
|
||||||
|
code += &format!(
|
||||||
|
"{}{escape}={},",
|
||||||
|
arg.keyword.content,
|
||||||
|
self.transpile_expr(arg.expr)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
code.push(')');
|
code.push(')');
|
||||||
code
|
code
|
||||||
|
|
|
@ -882,22 +882,26 @@ impl Ownership {
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct ArgsOwnership {
|
pub struct ArgsOwnership {
|
||||||
pub non_defaults: Vec<Ownership>,
|
pub non_defaults: Vec<(Option<Str>, Ownership)>,
|
||||||
pub var_params: Option<Ownership>,
|
pub var_params: Option<(Str, Ownership)>,
|
||||||
pub defaults: Vec<(Str, Ownership)>,
|
pub defaults: Vec<(Str, Ownership)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for ArgsOwnership {
|
impl fmt::Display for ArgsOwnership {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "(")?;
|
write!(f, "(")?;
|
||||||
for (i, o) in self.non_defaults.iter().enumerate() {
|
for (i, (name, o)) in self.non_defaults.iter().enumerate() {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
write!(f, ", ")?;
|
write!(f, ", ")?;
|
||||||
}
|
}
|
||||||
write!(f, "{o:?}")?;
|
if let Some(name) = name {
|
||||||
|
write!(f, "{name}: {o:?}")?;
|
||||||
|
} else {
|
||||||
|
write!(f, "{o:?}")?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if let Some(o) = self.var_params.as_ref() {
|
if let Some((name, o)) = self.var_params.as_ref() {
|
||||||
write!(f, ", ...{o:?}")?;
|
write!(f, ", ...{name}: {o:?}")?;
|
||||||
}
|
}
|
||||||
for (name, o) in self.defaults.iter() {
|
for (name, o) in self.defaults.iter() {
|
||||||
write!(f, ", {name} := {o:?}")?;
|
write!(f, ", {name} := {o:?}")?;
|
||||||
|
@ -909,8 +913,8 @@ impl fmt::Display for ArgsOwnership {
|
||||||
|
|
||||||
impl ArgsOwnership {
|
impl ArgsOwnership {
|
||||||
pub const fn new(
|
pub const fn new(
|
||||||
non_defaults: Vec<Ownership>,
|
non_defaults: Vec<(Option<Str>, Ownership)>,
|
||||||
var_params: Option<Ownership>,
|
var_params: Option<(Str, Ownership)>,
|
||||||
defaults: Vec<(Str, Ownership)>,
|
defaults: Vec<(Str, Ownership)>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
@ -1678,9 +1682,12 @@ impl Type {
|
||||||
Self::RefMut { .. } => Ownership::RefMut,
|
Self::RefMut { .. } => Ownership::RefMut,
|
||||||
_ => Ownership::Owned,
|
_ => Ownership::Owned,
|
||||||
};
|
};
|
||||||
nd_args.push(ownership);
|
nd_args.push((nd_param.name().cloned(), ownership));
|
||||||
}
|
}
|
||||||
let var_args = subr.var_params.as_ref().map(|t| t.typ().ownership());
|
let var_args = subr
|
||||||
|
.var_params
|
||||||
|
.as_ref()
|
||||||
|
.map(|t| (t.name().unwrap().clone(), t.typ().ownership()));
|
||||||
let mut d_args = vec![];
|
let mut d_args = vec![];
|
||||||
for d_param in subr.default_params.iter() {
|
for d_param in subr.default_params.iter() {
|
||||||
let ownership = match d_param.typ() {
|
let ownership = match d_param.typ() {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue