forked from M-Labs/nac3
virtual class tests
This commit is contained in:
parent
87dd0ee3cb
commit
75183c39fd
@ -77,8 +77,7 @@ fn find_subst(
|
|||||||
parents = [*id_a].to_vec();
|
parents = [*id_a].to_vec();
|
||||||
}
|
}
|
||||||
VirtualClassType(id_a) => {
|
VirtualClassType(id_a) => {
|
||||||
let a = ctx.get_class(*id_a);
|
parents = [*id_a].to_vec();
|
||||||
parents = a.parents.clone();
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
return Err("cannot substitute non-class type into virtual class".to_string());
|
return Err("cannot substitute non-class type into virtual class".to_string());
|
||||||
@ -486,4 +485,232 @@ mod tests {
|
|||||||
Err("different variables".to_string())
|
Err("different variables".to_string())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_class_generics() {
|
||||||
|
let mut ctx = basic_ctx();
|
||||||
|
let mut assumptions = HashMap::new();
|
||||||
|
|
||||||
|
let list = ctx.get_parametric_mut(LIST_TYPE);
|
||||||
|
let t = Rc::new(TypeVariable(list.params[0]));
|
||||||
|
list.base.methods.insert("head", FnDef {
|
||||||
|
args: create_tuple(vec![]),
|
||||||
|
result: Some(t.clone())
|
||||||
|
});
|
||||||
|
list.base.methods.insert("append", FnDef {
|
||||||
|
args: create_tuple(vec![t.clone()]),
|
||||||
|
result: None
|
||||||
|
});
|
||||||
|
|
||||||
|
let v0 = Rc::new(TypeVariable(ctx.add_variable(VarDef {
|
||||||
|
name: "V0",
|
||||||
|
bound: vec![],
|
||||||
|
})));
|
||||||
|
let v1 = Rc::new(TypeVariable(ctx.add_variable(VarDef {
|
||||||
|
name: "V1",
|
||||||
|
bound: vec![],
|
||||||
|
})));
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
resolve_call(
|
||||||
|
&ctx,
|
||||||
|
Some(ParametricType(LIST_TYPE, vec![v0.clone()]).into()),
|
||||||
|
"head",
|
||||||
|
create_tuple(vec![]),
|
||||||
|
&mut assumptions
|
||||||
|
),
|
||||||
|
Ok(Some(v0.clone()))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
resolve_call(
|
||||||
|
&ctx,
|
||||||
|
Some(ParametricType(LIST_TYPE, vec![v0.clone()]).into()),
|
||||||
|
"append",
|
||||||
|
create_tuple(vec![v0.clone()]),
|
||||||
|
&mut assumptions
|
||||||
|
),
|
||||||
|
Ok(None)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
resolve_call(
|
||||||
|
&ctx,
|
||||||
|
Some(ParametricType(LIST_TYPE, vec![v0.clone()]).into()),
|
||||||
|
"append",
|
||||||
|
create_tuple(vec![v1.clone()]),
|
||||||
|
&mut assumptions
|
||||||
|
),
|
||||||
|
Err("different variables".to_string())
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_virtual_class() {
|
||||||
|
let mut ctx = basic_ctx();
|
||||||
|
let mut assumptions = HashMap::new();
|
||||||
|
|
||||||
|
let foo = ctx.add_class(ClassDef {
|
||||||
|
base: TypeDef {
|
||||||
|
name: "Foo",
|
||||||
|
methods: HashMap::new(),
|
||||||
|
fields: HashMap::new()
|
||||||
|
},
|
||||||
|
parents: vec![]
|
||||||
|
});
|
||||||
|
|
||||||
|
let foo1 = ctx.add_class(ClassDef {
|
||||||
|
base: TypeDef {
|
||||||
|
name: "Foo1",
|
||||||
|
methods: HashMap::new(),
|
||||||
|
fields: HashMap::new()
|
||||||
|
},
|
||||||
|
parents: vec![foo]
|
||||||
|
});
|
||||||
|
|
||||||
|
let foo2 = ctx.add_class(ClassDef {
|
||||||
|
base: TypeDef {
|
||||||
|
name: "Foo2",
|
||||||
|
methods: HashMap::new(),
|
||||||
|
fields: HashMap::new()
|
||||||
|
},
|
||||||
|
parents: vec![foo1]
|
||||||
|
});
|
||||||
|
|
||||||
|
let bar = ctx.add_class(ClassDef {
|
||||||
|
base: TypeDef {
|
||||||
|
name: "bar",
|
||||||
|
methods: HashMap::new(),
|
||||||
|
fields: HashMap::new()
|
||||||
|
},
|
||||||
|
parents: vec![]
|
||||||
|
});
|
||||||
|
|
||||||
|
ctx.add_fn("foo", FnDef {
|
||||||
|
args: create_tuple(vec![VirtualClassType(foo).into()]),
|
||||||
|
result: None
|
||||||
|
});
|
||||||
|
ctx.add_fn("foo1", FnDef {
|
||||||
|
args: create_tuple(vec![VirtualClassType(foo1).into()]),
|
||||||
|
result: None
|
||||||
|
});
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
resolve_call(
|
||||||
|
&ctx,
|
||||||
|
None,
|
||||||
|
"foo",
|
||||||
|
create_tuple(vec![ClassType(foo).into()]),
|
||||||
|
&mut assumptions
|
||||||
|
),
|
||||||
|
Ok(None)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
resolve_call(
|
||||||
|
&ctx,
|
||||||
|
None,
|
||||||
|
"foo",
|
||||||
|
create_tuple(vec![ClassType(foo1).into()]),
|
||||||
|
&mut assumptions
|
||||||
|
),
|
||||||
|
Ok(None)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
resolve_call(
|
||||||
|
&ctx,
|
||||||
|
None,
|
||||||
|
"foo",
|
||||||
|
create_tuple(vec![ClassType(foo2).into()]),
|
||||||
|
&mut assumptions
|
||||||
|
),
|
||||||
|
Ok(None)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
resolve_call(
|
||||||
|
&ctx,
|
||||||
|
None,
|
||||||
|
"foo",
|
||||||
|
create_tuple(vec![ClassType(bar).into()]),
|
||||||
|
&mut assumptions
|
||||||
|
),
|
||||||
|
Err("not subtype".to_string())
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
resolve_call(
|
||||||
|
&ctx,
|
||||||
|
None,
|
||||||
|
"foo1",
|
||||||
|
create_tuple(vec![ClassType(foo1).into()]),
|
||||||
|
&mut assumptions
|
||||||
|
),
|
||||||
|
Ok(None)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
resolve_call(
|
||||||
|
&ctx,
|
||||||
|
None,
|
||||||
|
"foo1",
|
||||||
|
create_tuple(vec![ClassType(foo2).into()]),
|
||||||
|
&mut assumptions
|
||||||
|
),
|
||||||
|
Ok(None)
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
resolve_call(
|
||||||
|
&ctx,
|
||||||
|
None,
|
||||||
|
"foo1",
|
||||||
|
create_tuple(vec![ClassType(foo).into()]),
|
||||||
|
&mut assumptions
|
||||||
|
),
|
||||||
|
Err("not subtype".to_string())
|
||||||
|
);
|
||||||
|
|
||||||
|
// virtual class substitution
|
||||||
|
assert_eq!(
|
||||||
|
resolve_call(
|
||||||
|
&ctx,
|
||||||
|
None,
|
||||||
|
"foo",
|
||||||
|
create_tuple(vec![VirtualClassType(foo).into()]),
|
||||||
|
&mut assumptions
|
||||||
|
),
|
||||||
|
Ok(None)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
resolve_call(
|
||||||
|
&ctx,
|
||||||
|
None,
|
||||||
|
"foo",
|
||||||
|
create_tuple(vec![VirtualClassType(foo1).into()]),
|
||||||
|
&mut assumptions
|
||||||
|
),
|
||||||
|
Ok(None)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
resolve_call(
|
||||||
|
&ctx,
|
||||||
|
None,
|
||||||
|
"foo",
|
||||||
|
create_tuple(vec![VirtualClassType(foo2).into()]),
|
||||||
|
&mut assumptions
|
||||||
|
),
|
||||||
|
Ok(None)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
resolve_call(
|
||||||
|
&ctx,
|
||||||
|
None,
|
||||||
|
"foo",
|
||||||
|
create_tuple(vec![VirtualClassType(bar).into()]),
|
||||||
|
&mut assumptions
|
||||||
|
),
|
||||||
|
Err("not subtype".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user