mirror of
https://github.com/erg-lang/erg.git
synced 2025-09-27 11:59:05 +00:00
fix(compiler): infinite recursion bug of derefine
This commit is contained in:
parent
3aeb63f51b
commit
7389f68e3e
4 changed files with 21 additions and 3 deletions
|
@ -23,7 +23,7 @@
|
||||||
'''
|
'''
|
||||||
'''erg
|
'''erg
|
||||||
assert [1, 1, 2].dedup() == [1, 2]
|
assert [1, 1, 2].dedup() == [1, 2]
|
||||||
assert [0.0, 0.1, 10.0, 20.0, 20.1].dedup((lhs, rhs) -> abs(lhs - rhs) < 1.0) == [0.0, 10.0, 20.1]
|
assert [0.0, 0.1, 10.0, 20.0, 20.1].dedup((lhs, rhs) -> abs(lhs - rhs) < 1.0) == [0.1, 10.0, 20.1]
|
||||||
'''
|
'''
|
||||||
dedup: |T: Type|(self: Array(T, _), same_bucket := (T, T) -> Bool) -> Array(T, _)
|
dedup: |T: Type|(self: Array(T, _), same_bucket := (T, T) -> Bool) -> Array(T, _)
|
||||||
'''
|
'''
|
||||||
|
|
|
@ -1879,9 +1879,13 @@ impl Type {
|
||||||
let name = fv.unbound_name().unwrap();
|
let name = fv.unbound_name().unwrap();
|
||||||
let level = fv.level().unwrap();
|
let level = fv.level().unwrap();
|
||||||
if let Some((sub, sup)) = fv.get_subsup() {
|
if let Some((sub, sup)) = fv.get_subsup() {
|
||||||
|
// if fv == ?T(:> {1, 2}, <: Sub(?T)), derefine() will cause infinite loop
|
||||||
|
// so we need to force linking
|
||||||
|
fv.forced_undoable_link(&sub);
|
||||||
let constraint = Constraint::new_sandwiched(sub.derefine(), sup.derefine());
|
let constraint = Constraint::new_sandwiched(sub.derefine(), sup.derefine());
|
||||||
// not `.update_constraint`
|
let free = Self::FreeVar(Free::new_named_unbound(name, level, constraint));
|
||||||
Self::FreeVar(Free::new_named_unbound(name, level, constraint))
|
fv.undo();
|
||||||
|
free
|
||||||
} else {
|
} else {
|
||||||
let t = fv.get_type().unwrap().derefine();
|
let t = fv.get_type().unwrap().derefine();
|
||||||
let constraint = Constraint::new_type_of(t);
|
let constraint = Constraint::new_type_of(t);
|
||||||
|
|
9
tests/should_ok/array.er
Normal file
9
tests/should_ok/array.er
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
assert [1, 2].concat([3, 4]) == [1, 2, 3, 4]
|
||||||
|
|
||||||
|
assert [1, 2, 3, 1, 2].count(1) == 2
|
||||||
|
assert ["a", "b", "c"].count("a") == 1
|
||||||
|
|
||||||
|
assert [1, 1, 2].dedup() == [1, 2]
|
||||||
|
assert [0.0, 0.1, 10.0, 20.0, 20.1].dedup((lhs, rhs) -> abs(lhs - rhs) < 1.0) == [0.1, 10.0, 20.1]
|
||||||
|
|
||||||
|
assert [-2, -1, 0, 1, 2].partition(x -> x >= 0) == ([0, 1, 2], [-2, -1])
|
|
@ -11,6 +11,11 @@ fn exec_advanced_type_spec() -> Result<(), ()> {
|
||||||
expect_success("tests/should_ok/advanced_type_spec.er")
|
expect_success("tests/should_ok/advanced_type_spec.er")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn exec_array() -> Result<(), ()> {
|
||||||
|
expect_success("tests/should_ok/array.er")
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn exec_assert_cast() -> Result<(), ()> {
|
fn exec_assert_cast() -> Result<(), ()> {
|
||||||
expect_success("examples/assert_cast.er")
|
expect_success("examples/assert_cast.er")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue