mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 18:58:30 +00:00
fix: function subtyping bug
This commit is contained in:
parent
9774a628fb
commit
d87c5d552c
6 changed files with 43 additions and 18 deletions
|
@ -383,15 +383,24 @@ impl Context {
|
|||
};
|
||||
// () -> Never <: () -> Int <: () -> Object
|
||||
// (Object) -> Int <: (Int) -> Int <: (Never) -> Int
|
||||
// (Int, Int) -> Int <!: (Int) -> Int
|
||||
// (Int, n := Int) -> Int <: (Int, Int) -> Int
|
||||
// (Int, Int, n := Int) -> Int <!: (Int, n := Int) -> Int
|
||||
// (Int, n := Int, m := Int) -> Int <: (Int, Int) -> Int
|
||||
// (Int, n := Int) -> Int <!: (Int, Int, Int) -> Int
|
||||
// (*Int) -> Int <: (Int, Int) -> Int
|
||||
// (*Int) -> Int !<: (n := Int, m := Int) -> Int
|
||||
// (self: Self, T) -> U <: T -> U
|
||||
let len_judge = ls.non_default_params.len()
|
||||
<= rs.non_default_params.len() + rs.default_params.len()
|
||||
|| rs.var_params.is_some();
|
||||
// && ls.default_params.len() <= rs.default_params.len();
|
||||
let len_judge = (if rs.default_params.is_empty() {
|
||||
ls.non_default_params.len() == rs.non_default_params.len()
|
||||
} else {
|
||||
ls.non_default_params.len() >= rs.non_default_params.len()
|
||||
&& ls.non_default_params.len()
|
||||
<= rs.non_default_params.len() + rs.default_params.len()
|
||||
} && ls.default_params.len() <= rs.default_params.len())
|
||||
|| (ls.default_params.is_empty() && rs.var_params.is_some())
|
||||
|| (ls.non_default_params.is_empty() && rs.kw_var_params.is_some())
|
||||
|| (rs.var_params.is_some() && rs.kw_var_params.is_some());
|
||||
let rhs_ret = rs
|
||||
.return_t
|
||||
.clone()
|
||||
|
|
|
@ -484,17 +484,14 @@ impl Context {
|
|||
}
|
||||
};
|
||||
if let Some(decl_pt) = opt_decl_t {
|
||||
if kind.is_var_params() {
|
||||
let spec_t = unknown_len_list_t(spec_t.clone());
|
||||
if let Err(es) = self.sub_unify(
|
||||
decl_pt.typ(),
|
||||
&spec_t,
|
||||
&sig.t_spec.as_ref().ok_or(sig),
|
||||
None,
|
||||
) {
|
||||
return Err((spec_t, errs.concat(es)));
|
||||
}
|
||||
} else if let Err(es) = self.sub_unify(
|
||||
let spec_t = if kind.is_var_params() {
|
||||
unknown_len_list_t(spec_t.clone())
|
||||
} else if kind.is_kw_var_params() {
|
||||
str_dict_t(spec_t.clone())
|
||||
} else {
|
||||
spec_t.clone()
|
||||
};
|
||||
if let Err(es) = self.sub_unify(
|
||||
decl_pt.typ(),
|
||||
&spec_t,
|
||||
&sig.t_spec.as_ref().ok_or(sig),
|
||||
|
|
|
@ -619,7 +619,7 @@ impl Context {
|
|||
}
|
||||
}
|
||||
if let Some(kw_var_params) = &mut params.kw_var_params {
|
||||
if let Some(pt) = &subr_t.var_params {
|
||||
if let Some(pt) = &subr_t.kw_var_params {
|
||||
let pt = pt.clone().map_type(&mut str_dict_t);
|
||||
if let Err(es) = self.assign_param(
|
||||
kw_var_params,
|
||||
|
|
|
@ -7,3 +7,14 @@ _: Int -> Str = id_or_int # ERR
|
|||
|
||||
g x: Int := 1, y: Int := "a" = x + y # ERR
|
||||
_: (Int, Int) -> Int = g
|
||||
|
||||
check f: (Int, n := Int) -> Int = f(1)
|
||||
check2 f: (m := Int, n := Int) -> Int = f(m:=1, n:=2)
|
||||
f1(x: Int, y, n := 1) = x + y + n
|
||||
f2(x: Int, y: Int) = x + y
|
||||
f3(*x: Int) = x[0]
|
||||
f4(**x: Int) = x["a"]
|
||||
_ = check f1 # ERR
|
||||
_ = check2 f2 # ERR
|
||||
_ = check2 f3 # ERR
|
||||
_ = check f4 # ERR
|
||||
|
|
|
@ -18,3 +18,11 @@ _: (Int, Int, Nat) -> Int = f
|
|||
_: (Int, Int, _: {1}) -> Int = f
|
||||
_: Int -> Int = id_or_int
|
||||
_: Str -> Str = id_or_int
|
||||
|
||||
check f: (Int, n := Int) -> Int = f(1)
|
||||
check2 f: (m := Int, n := Int) -> Int = f(m:=1, n:=2)
|
||||
f2(m: Int := 1, n := 1, l := 1) = m + n + l
|
||||
f3(*x: Int, **y: Int) = len(x) + y.get("n", 0)
|
||||
_ = check2 f2
|
||||
_ = check f3
|
||||
_ = check2 f3
|
||||
|
|
|
@ -509,7 +509,7 @@ fn exec_advanced_type_spec_err() -> Result<(), ()> {
|
|||
|
||||
#[test]
|
||||
fn exec_args() -> Result<(), ()> {
|
||||
expect_failure("tests/should_err/args.er", 0, 19)
|
||||
expect_failure("tests/should_err/args.er", 0, 20)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -559,7 +559,7 @@ fn exec_collection_err() -> Result<(), ()> {
|
|||
|
||||
#[test]
|
||||
fn exec_default_param_err() -> Result<(), ()> {
|
||||
expect_failure("tests/should_err/default_param.er", 0, 4)
|
||||
expect_failure("tests/should_err/default_param.er", 0, 8)
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue