mirror of
https://github.com/erg-lang/erg.git
synced 2025-08-04 10:49:54 +00:00
Merge branch 'main' into named_tuple
This commit is contained in:
commit
5ac0012255
9 changed files with 62 additions and 10 deletions
|
@ -495,6 +495,14 @@ macro_rules! log {
|
|||
}
|
||||
}};
|
||||
|
||||
(backtrace) => {{
|
||||
if cfg!(feature = "debug") {
|
||||
use $crate::style::*;
|
||||
$crate::debug_info!();
|
||||
println!("\n{}", std::backtrace::Backtrace::capture());
|
||||
}
|
||||
}};
|
||||
|
||||
($($arg: tt)*) => {{
|
||||
if cfg!(feature = "debug") {
|
||||
use $crate::style::*;
|
||||
|
|
|
@ -77,7 +77,7 @@ impl Context {
|
|||
.quantify();
|
||||
let t_filter = nd_func(
|
||||
vec![
|
||||
kw(KW_FUNC, nd_func(vec![anon(T.clone())], None, T.clone())),
|
||||
kw(KW_FUNC, nd_func(vec![anon(T.clone())], None, Bool)),
|
||||
kw(KW_ITERABLE, poly(ITERABLE, vec![ty_tp(T.clone())])),
|
||||
],
|
||||
None,
|
||||
|
|
|
@ -785,7 +785,7 @@ impl Context {
|
|||
readable_name(name.inspect()),
|
||||
&expect,
|
||||
&found,
|
||||
e.core.get_hint().map(|s| s.to_string()),
|
||||
// e.core.get_hint().map(|s| s.to_string()),
|
||||
)
|
||||
})
|
||||
.collect(),
|
||||
|
|
|
@ -145,10 +145,10 @@ impl<'c, 'l, L: Locational> Unifier<'c, 'l, L> {
|
|||
self.occur_inner(lhs, l)?;
|
||||
self.occur_inner(lhs, r)
|
||||
}
|
||||
/*(Or(l, r), rhs) | (And(l, r), rhs) => {
|
||||
self.occur_inner(l, rhs, loc)?;
|
||||
self.occur_inner(r, rhs, loc)
|
||||
}*/
|
||||
(Or(l, r), rhs) | (And(l, r), rhs) => {
|
||||
self.occur_inner(l, rhs)?;
|
||||
self.occur_inner(r, rhs)
|
||||
}
|
||||
_ => Ok(()),
|
||||
}
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ impl<'c, 'l, L: Locational> Unifier<'c, 'l, L> {
|
|||
(FreeVar(fv), _) if fv.is_linked() => self.occur_inner(&fv.crack(), maybe_sup),
|
||||
(_, FreeVar(fv)) if fv.is_linked() => self.occur_inner(maybe_sub, &fv.crack()),
|
||||
(FreeVar(sub), FreeVar(sup)) => {
|
||||
if sub.is_unbound() && sup.is_unbound() && sub == sup {
|
||||
if sub.is_unbound() && sup.is_unbound() && sub.addr_eq(sup) {
|
||||
Err(TyCheckErrors::from(TyCheckError::subtyping_error(
|
||||
self.ctx.cfg.input.clone(),
|
||||
line!() as usize,
|
||||
|
@ -168,6 +168,20 @@ impl<'c, 'l, L: Locational> Unifier<'c, 'l, L> {
|
|||
self.ctx.caused_by(),
|
||||
)))
|
||||
} else {
|
||||
if sub.constraint_is_sandwiched() {
|
||||
let (sub_t, sup_t) = sub.get_subsup().unwrap();
|
||||
sub.do_avoiding_recursion(|| {
|
||||
self.occur_inner(&sub_t, maybe_sup)?;
|
||||
self.occur_inner(&sup_t, maybe_sup)
|
||||
})?;
|
||||
}
|
||||
if sup.constraint_is_sandwiched() {
|
||||
let (sub_t, sup_t) = sup.get_subsup().unwrap();
|
||||
sup.do_avoiding_recursion(|| {
|
||||
self.occur_inner(maybe_sub, &sub_t)?;
|
||||
self.occur_inner(maybe_sub, &sup_t)
|
||||
})?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -590,7 +590,6 @@ mod test {
|
|||
name,
|
||||
&expect,
|
||||
&found,
|
||||
None,
|
||||
);
|
||||
errors.push(err);
|
||||
|
||||
|
|
|
@ -178,7 +178,7 @@ impl TyCheckError {
|
|||
name: &str,
|
||||
expect: &Type,
|
||||
found: &Type,
|
||||
hint: Option<String>,
|
||||
// hint: Option<String>,
|
||||
) -> Self {
|
||||
let name = name.with_color(Color::Yellow);
|
||||
let mut expct = StyledStrings::default();
|
||||
|
@ -198,13 +198,19 @@ impl TyCheckError {
|
|||
"english" =>fnd.push_str("but found: "),
|
||||
);
|
||||
fnd.push_str_with_color_and_attr(format!("{found}"), ERR, ATTR);
|
||||
let hint = switch_lang!(
|
||||
"japanese" => "自身を返す関数は定義できません",
|
||||
"simplified_chinese" => "不能定义返回自身的函数",
|
||||
"traditional_chinese" => "不能定義返回自身的函數",
|
||||
"english" => "cannot define a function that returns itself",
|
||||
);
|
||||
|
||||
Self::new(
|
||||
ErrorCore::new(
|
||||
vec![SubMessage::ambiguous_new(
|
||||
loc,
|
||||
vec![expct.to_string(), fnd.to_string()],
|
||||
hint,
|
||||
Some(hint.into()),
|
||||
)],
|
||||
switch_lang!(
|
||||
"japanese" => format!("{name}の戻り値の型が違います"),
|
||||
|
|
7
tests/should_err/recursive_fn.er
Normal file
7
tests/should_err/recursive_fn.er
Normal file
|
@ -0,0 +1,7 @@
|
|||
f() = f # ERR
|
||||
|
||||
g 0 = 0
|
||||
g _: Int = g # ERR
|
||||
|
||||
# left() = right() # ERR
|
||||
# right() = left
|
8
tests/should_ok/iterator.er
Normal file
8
tests/should_ok/iterator.er
Normal file
|
@ -0,0 +1,8 @@
|
|||
for! enumerate(0..3), ((i, j),) =>
|
||||
assert i == j
|
||||
for! zip(0..3, 0..3), ((i, j),) =>
|
||||
assert i == j
|
||||
for! filter(x -> x > 1, 0..3), i =>
|
||||
assert i > 1
|
||||
for! map(x -> "\{x}", [1, 2, 3]), s =>
|
||||
assert str(s) == s
|
|
@ -394,6 +394,11 @@ fn exec_invalid_param() -> Result<(), ()> {
|
|||
expect_failure("tests/should_err/invalid_param.er", 0, 3)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exec_iterator() -> Result<(), ()> {
|
||||
expect_success("tests/should_ok/iterator.er", 0)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exec_move_check() -> Result<(), ()> {
|
||||
expect_failure("examples/move_check.er", 1, 1)
|
||||
|
@ -468,6 +473,11 @@ fn exec_quantified_err() -> Result<(), ()> {
|
|||
expect_failure("tests/should_err/quantified.er", 0, 3)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exec_recursive_fn_err() -> Result<(), ()> {
|
||||
expect_failure("tests/should_err/recursive_fn.er", 0, 2)
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn exec_refinement_err() -> Result<(), ()> {
|
||||
expect_failure("tests/should_err/refinement.er", 0, 8)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue