forked from M-Labs/nac3
modified occur check
This commit is contained in:
parent
b3d849ea7a
commit
4f81690128
|
@ -162,7 +162,7 @@ impl TestEnvironment {
|
||||||
#[test_case(indoc! {"
|
#[test_case(indoc! {"
|
||||||
f = lambda x: True
|
f = lambda x: True
|
||||||
a = [1, 2, 3]
|
a = [1, 2, 3]
|
||||||
b = [f(x) for x in a]
|
b = [f(x) for x in a if f(x)]
|
||||||
"},
|
"},
|
||||||
[("a", "list[int32]"), ("b", "list[bool]"), ("f", "fn[[x=int32], bool]")].iter().cloned().collect()
|
[("a", "list[int32]"), ("b", "list[bool]"), ("f", "fn[[x=int32], bool]")].iter().cloned().collect()
|
||||||
; "listcomp test")]
|
; "listcomp test")]
|
||||||
|
|
|
@ -259,12 +259,13 @@ impl Unifier {
|
||||||
|
|
||||||
let (ty_a, ty_b) = { (ty_a_cell.borrow(), ty_b_cell.borrow()) };
|
let (ty_a, ty_b) = { (ty_a_cell.borrow(), ty_b_cell.borrow()) };
|
||||||
|
|
||||||
self.occur_check(a, b)?;
|
|
||||||
match (&*ty_a, &*ty_b) {
|
match (&*ty_a, &*ty_b) {
|
||||||
(TypeEnum::TVar { .. }, _) => {
|
(TypeEnum::TVar { .. }, _) => {
|
||||||
|
self.occur_check(a, b)?;
|
||||||
self.set_a_to_b(a, b);
|
self.set_a_to_b(a, b);
|
||||||
}
|
}
|
||||||
(TSeq { map: map1 }, TSeq { .. }) => {
|
(TSeq { map: map1 }, TSeq { .. }) => {
|
||||||
|
self.occur_check(a, b)?;
|
||||||
drop(ty_b);
|
drop(ty_b);
|
||||||
if let TypeEnum::TSeq { map: map2 } = &mut *ty_b_cell.as_ref().borrow_mut() {
|
if let TypeEnum::TSeq { map: map2 } = &mut *ty_b_cell.as_ref().borrow_mut() {
|
||||||
// unify them to map2
|
// unify them to map2
|
||||||
|
@ -281,6 +282,7 @@ impl Unifier {
|
||||||
self.set_a_to_b(a, b);
|
self.set_a_to_b(a, b);
|
||||||
}
|
}
|
||||||
(TSeq { map: map1 }, TTuple { ty: types }) => {
|
(TSeq { map: map1 }, TTuple { ty: types }) => {
|
||||||
|
self.occur_check(a, b)?;
|
||||||
let len = types.len() as i32;
|
let len = types.len() as i32;
|
||||||
for (k, v) in map1.iter() {
|
for (k, v) in map1.iter() {
|
||||||
// handle negative index
|
// handle negative index
|
||||||
|
@ -297,6 +299,7 @@ impl Unifier {
|
||||||
self.set_a_to_b(a, b);
|
self.set_a_to_b(a, b);
|
||||||
}
|
}
|
||||||
(TSeq { map: map1 }, TList { ty }) => {
|
(TSeq { map: map1 }, TList { ty }) => {
|
||||||
|
self.occur_check(a, b)?;
|
||||||
for v in map1.values() {
|
for v in map1.values() {
|
||||||
self.unify(*v, *ty)?;
|
self.unify(*v, *ty)?;
|
||||||
}
|
}
|
||||||
|
@ -320,6 +323,7 @@ impl Unifier {
|
||||||
self.set_a_to_b(a, b);
|
self.set_a_to_b(a, b);
|
||||||
}
|
}
|
||||||
(TRecord { fields: fields1 }, TRecord { .. }) => {
|
(TRecord { fields: fields1 }, TRecord { .. }) => {
|
||||||
|
self.occur_check(a, b)?;
|
||||||
drop(ty_b);
|
drop(ty_b);
|
||||||
if let TypeEnum::TRecord { fields: fields2 } = &mut *ty_b_cell.as_ref().borrow_mut()
|
if let TypeEnum::TRecord { fields: fields2 } = &mut *ty_b_cell.as_ref().borrow_mut()
|
||||||
{
|
{
|
||||||
|
@ -341,6 +345,7 @@ impl Unifier {
|
||||||
fields: fields2, ..
|
fields: fields2, ..
|
||||||
},
|
},
|
||||||
) => {
|
) => {
|
||||||
|
self.occur_check(a, b)?;
|
||||||
for (key, value) in fields1.iter() {
|
for (key, value) in fields1.iter() {
|
||||||
if let Some(ty) = fields2.get(key) {
|
if let Some(ty) = fields2.get(key) {
|
||||||
self.unify(*ty, *value)?;
|
self.unify(*ty, *value)?;
|
||||||
|
@ -351,6 +356,7 @@ impl Unifier {
|
||||||
self.set_a_to_b(a, b);
|
self.set_a_to_b(a, b);
|
||||||
}
|
}
|
||||||
(TRecord { .. }, TVirtual { ty }) => {
|
(TRecord { .. }, TVirtual { ty }) => {
|
||||||
|
self.occur_check(a, b)?;
|
||||||
self.unify(a, *ty)?;
|
self.unify(a, *ty)?;
|
||||||
}
|
}
|
||||||
(
|
(
|
||||||
|
@ -387,6 +393,7 @@ impl Unifier {
|
||||||
self.set_a_to_b(a, b);
|
self.set_a_to_b(a, b);
|
||||||
}
|
}
|
||||||
(TCall { calls }, TFunc(signature)) => {
|
(TCall { calls }, TFunc(signature)) => {
|
||||||
|
self.occur_check(a, b)?;
|
||||||
let required: Vec<String> = signature
|
let required: Vec<String> = signature
|
||||||
.args
|
.args
|
||||||
.iter()
|
.iter()
|
||||||
|
|
Loading…
Reference in New Issue