Merge branch 'main' into named_tuple

This commit is contained in:
Shunsuke Shibayama 2023-08-18 02:12:37 +09:00
commit 5ac0012255
9 changed files with 62 additions and 10 deletions

View file

@ -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::*;

View file

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

View file

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

View file

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

View file

@ -590,7 +590,6 @@ mod test {
name,
&expect,
&found,
None,
);
errors.push(err);

View file

@ -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}の戻り値の型が違います"),

View file

@ -0,0 +1,7 @@
f() = f # ERR
g 0 = 0
g _: Int = g # ERR
# left() = right() # ERR
# right() = left

View 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

View file

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