forked from M-Labs/nac3
fixed and enabled inference_core tests
This commit is contained in:
parent
8ade8c7b1f
commit
fa2fc1db54
|
@ -198,394 +198,417 @@ pub fn resolve_call(
|
||||||
resolve_call_rec(ctx, &None, obj, func, args)
|
resolve_call_rec(ctx, &None, obj, func, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[cfg(test)]
|
#[cfg(test)]
|
||||||
// mod tests {
|
mod tests {
|
||||||
// use super::*;
|
use std::rc::Rc;
|
||||||
// use crate::primitives::*;
|
use super::*;
|
||||||
|
use crate::context::TopLevelContext;
|
||||||
|
use crate::primitives::*;
|
||||||
|
|
||||||
// #[test]
|
fn get_inference_context(ctx: TopLevelContext) -> InferenceContext {
|
||||||
// fn test_simple_generic() {
|
InferenceContext::new(ctx, Box::new(|_| Err("unbounded identifier".into())))
|
||||||
// let mut ctx = basic_ctx();
|
}
|
||||||
|
|
||||||
// assert_eq!(
|
#[test]
|
||||||
// resolve_call(&ctx, None, "int32", &[PrimitiveType(FLOAT_TYPE).into()]),
|
fn test_simple_generic() {
|
||||||
// Ok(Some(PrimitiveType(INT32_TYPE).into()))
|
let mut ctx = basic_ctx();
|
||||||
// );
|
let v1 = ctx.add_variable(VarDef {
|
||||||
|
name: "V1",
|
||||||
|
bound: vec![
|
||||||
|
ctx.get_primitive(INT32_TYPE),
|
||||||
|
ctx.get_primitive(FLOAT_TYPE),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
let v1 = ctx.get_variable(v1);
|
||||||
|
let v2 = ctx.add_variable(VarDef {
|
||||||
|
name: "V2",
|
||||||
|
bound: vec![
|
||||||
|
ctx.get_primitive(BOOL_TYPE),
|
||||||
|
ctx.get_primitive(INT32_TYPE),
|
||||||
|
ctx.get_primitive(FLOAT_TYPE),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
let v2 = ctx.get_variable(v2);
|
||||||
|
let ctx = get_inference_context(ctx);
|
||||||
|
|
||||||
// assert_eq!(
|
assert_eq!(
|
||||||
// resolve_call(&ctx, None, "int32", &[PrimitiveType(INT32_TYPE).into()],),
|
resolve_call(&ctx, None, "int32", &[ctx.get_primitive(FLOAT_TYPE)]),
|
||||||
// Ok(Some(PrimitiveType(INT32_TYPE).into()))
|
Ok(Some(ctx.get_primitive(INT32_TYPE).into()))
|
||||||
// );
|
);
|
||||||
|
|
||||||
// assert_eq!(
|
assert_eq!(
|
||||||
// resolve_call(&ctx, None, "float", &[PrimitiveType(INT32_TYPE).into()]),
|
resolve_call(&ctx, None, "int32", &[ctx.get_primitive(INT32_TYPE)],),
|
||||||
// Ok(Some(PrimitiveType(FLOAT_TYPE).into()))
|
Ok(Some(ctx.get_primitive(INT32_TYPE).into()))
|
||||||
// );
|
);
|
||||||
|
|
||||||
// assert_eq!(
|
assert_eq!(
|
||||||
// resolve_call(&ctx, None, "float", &[PrimitiveType(BOOL_TYPE).into()]),
|
resolve_call(&ctx, None, "float", &[ctx.get_primitive(INT32_TYPE)]),
|
||||||
// Err("different domain".to_string())
|
Ok(Some(ctx.get_primitive(FLOAT_TYPE).into()))
|
||||||
// );
|
);
|
||||||
|
|
||||||
// assert_eq!(
|
assert_eq!(
|
||||||
// resolve_call(&ctx, None, "float", &[]),
|
resolve_call(&ctx, None, "float", &[ctx.get_primitive(BOOL_TYPE)]),
|
||||||
// Err("incorrect parameter number".to_string())
|
Err("different domain".to_string())
|
||||||
// );
|
);
|
||||||
|
|
||||||
// let v1 = ctx.add_variable(VarDef {
|
assert_eq!(
|
||||||
// name: "V1",
|
resolve_call(&ctx, None, "float", &[]),
|
||||||
// bound: vec![
|
Err("incorrect parameter number".to_string())
|
||||||
// PrimitiveType(INT32_TYPE).into(),
|
);
|
||||||
// PrimitiveType(FLOAT_TYPE).into(),
|
|
||||||
// ],
|
|
||||||
// });
|
|
||||||
|
|
||||||
// assert_eq!(
|
|
||||||
// resolve_call(&ctx, None, "float", &[TypeVariable(v1).into()]),
|
|
||||||
// Ok(Some(PrimitiveType(FLOAT_TYPE).into()))
|
|
||||||
// );
|
|
||||||
|
|
||||||
// let v2 = ctx.add_variable(VarDef {
|
assert_eq!(
|
||||||
// name: "V2",
|
resolve_call(&ctx, None, "float", &[v1]),
|
||||||
// bound: vec![
|
Ok(Some(ctx.get_primitive(FLOAT_TYPE)))
|
||||||
// PrimitiveType(BOOL_TYPE).into(),
|
);
|
||||||
// PrimitiveType(INT32_TYPE).into(),
|
|
||||||
// PrimitiveType(FLOAT_TYPE).into(),
|
|
||||||
// ],
|
|
||||||
// });
|
|
||||||
|
|
||||||
// assert_eq!(
|
|
||||||
// resolve_call(&ctx, None, "float", &[TypeVariable(v2).into()]),
|
|
||||||
// Err("different domain".to_string())
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[test]
|
assert_eq!(
|
||||||
// fn test_methods() {
|
resolve_call(&ctx, None, "float", &[v2]),
|
||||||
// let mut ctx = basic_ctx();
|
Err("different domain".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// let v0 = Rc::new(TypeVariable(ctx.add_variable(VarDef {
|
#[test]
|
||||||
// name: "V0",
|
fn test_methods() {
|
||||||
// bound: vec![],
|
let mut ctx = basic_ctx();
|
||||||
// })));
|
|
||||||
// let v1 = Rc::new(TypeVariable(ctx.add_variable(VarDef {
|
|
||||||
// name: "V1",
|
|
||||||
// bound: vec![
|
|
||||||
// PrimitiveType(INT32_TYPE).into(),
|
|
||||||
// PrimitiveType(FLOAT_TYPE).into(),
|
|
||||||
// ],
|
|
||||||
// })));
|
|
||||||
// let v2 = Rc::new(TypeVariable(ctx.add_variable(VarDef {
|
|
||||||
// name: "V2",
|
|
||||||
// bound: vec![
|
|
||||||
// PrimitiveType(INT32_TYPE).into(),
|
|
||||||
// PrimitiveType(FLOAT_TYPE).into(),
|
|
||||||
// ],
|
|
||||||
// })));
|
|
||||||
// let v3 = Rc::new(TypeVariable(ctx.add_variable(VarDef {
|
|
||||||
// name: "V3",
|
|
||||||
// bound: vec![
|
|
||||||
// PrimitiveType(BOOL_TYPE).into(),
|
|
||||||
// PrimitiveType(INT32_TYPE).into(),
|
|
||||||
// PrimitiveType(FLOAT_TYPE).into(),
|
|
||||||
// ],
|
|
||||||
// })));
|
|
||||||
|
|
||||||
// let int32 = Rc::new(PrimitiveType(INT32_TYPE));
|
let v0 = ctx.add_variable(VarDef {
|
||||||
// let int64 = Rc::new(PrimitiveType(INT64_TYPE));
|
name: "V0",
|
||||||
|
bound: vec![],
|
||||||
|
});
|
||||||
|
let v0 = ctx.get_variable(v0);
|
||||||
|
let v1 = ctx.add_variable(VarDef {
|
||||||
|
name: "V1",
|
||||||
|
bound: vec![
|
||||||
|
ctx.get_primitive(INT32_TYPE).into(),
|
||||||
|
ctx.get_primitive(FLOAT_TYPE).into(),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
let v1 = ctx.get_variable(v1);
|
||||||
|
let v2 = ctx.add_variable(VarDef {
|
||||||
|
name: "V2",
|
||||||
|
bound: vec![
|
||||||
|
ctx.get_primitive(INT32_TYPE).into(),
|
||||||
|
ctx.get_primitive(FLOAT_TYPE).into(),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
let v2 = ctx.get_variable(v2);
|
||||||
|
let v3 = ctx.add_variable(VarDef {
|
||||||
|
name: "V3",
|
||||||
|
bound: vec![
|
||||||
|
ctx.get_primitive(BOOL_TYPE).into(),
|
||||||
|
ctx.get_primitive(INT32_TYPE).into(),
|
||||||
|
ctx.get_primitive(FLOAT_TYPE).into(),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
let v3 = ctx.get_variable(v3);
|
||||||
|
|
||||||
// // simple cases
|
let int32 = ctx.get_primitive(INT32_TYPE);
|
||||||
// assert_eq!(
|
let int64 = ctx.get_primitive(INT64_TYPE);
|
||||||
// resolve_call(&ctx, Some(int32.clone()), "__add__", &[int32.clone()]),
|
let ctx = get_inference_context(ctx);
|
||||||
// Ok(Some(int32.clone()))
|
|
||||||
// );
|
|
||||||
|
|
||||||
// assert_ne!(
|
// simple cases
|
||||||
// resolve_call(&ctx, Some(int32.clone()), "__add__", &[int32.clone()]),
|
assert_eq!(
|
||||||
// Ok(Some(int64.clone()))
|
resolve_call(&ctx, Some(int32.clone()), "__add__", &[int32.clone()]),
|
||||||
// );
|
Ok(Some(int32.clone()))
|
||||||
|
);
|
||||||
|
|
||||||
// assert_eq!(
|
assert_ne!(
|
||||||
// resolve_call(&ctx, Some(int32.clone()), "__add__", &[int64.clone()]),
|
resolve_call(&ctx, Some(int32.clone()), "__add__", &[int32.clone()]),
|
||||||
// Err("not equal".to_string())
|
Ok(Some(int64.clone()))
|
||||||
// );
|
);
|
||||||
|
|
||||||
// // with type variables
|
assert_eq!(
|
||||||
// assert_eq!(
|
resolve_call(&ctx, Some(int32.clone()), "__add__", &[int64.clone()]),
|
||||||
// resolve_call(&ctx, Some(v1.clone()), "__add__", &[v1.clone()]),
|
Err("not equal".to_string())
|
||||||
// Ok(Some(v1.clone()))
|
);
|
||||||
// );
|
|
||||||
// assert_eq!(
|
|
||||||
// resolve_call(&ctx, Some(v0.clone()), "__add__", &[v2.clone()]),
|
|
||||||
// Err("unbounded type var".to_string())
|
|
||||||
// );
|
|
||||||
// assert_eq!(
|
|
||||||
// resolve_call(&ctx, Some(v1.clone()), "__add__", &[v0.clone()]),
|
|
||||||
// Err("different domain".to_string())
|
|
||||||
// );
|
|
||||||
// assert_eq!(
|
|
||||||
// resolve_call(&ctx, Some(v1.clone()), "__add__", &[v2.clone()]),
|
|
||||||
// Err("different domain".to_string())
|
|
||||||
// );
|
|
||||||
// assert_eq!(
|
|
||||||
// resolve_call(&ctx, Some(v1.clone()), "__add__", &[v3.clone()]),
|
|
||||||
// Err("different domain".to_string())
|
|
||||||
// );
|
|
||||||
// assert_eq!(
|
|
||||||
// resolve_call(&ctx, Some(v3.clone()), "__add__", &[v1.clone()]),
|
|
||||||
// Err("no such function".to_string())
|
|
||||||
// );
|
|
||||||
// assert_eq!(
|
|
||||||
// resolve_call(&ctx, Some(v3.clone()), "__add__", &[v3.clone()]),
|
|
||||||
// Err("no such function".to_string())
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[test]
|
// with type variables
|
||||||
// fn test_multi_generic() {
|
assert_eq!(
|
||||||
// let mut ctx = basic_ctx();
|
resolve_call(&ctx, Some(v1.clone()), "__add__", &[v1.clone()]),
|
||||||
// let v0 = Rc::new(TypeVariable(ctx.add_variable(VarDef {
|
Ok(Some(v1.clone()))
|
||||||
// name: "V0",
|
);
|
||||||
// bound: vec![],
|
assert_eq!(
|
||||||
// })));
|
resolve_call(&ctx, Some(v0.clone()), "__add__", &[v2.clone()]),
|
||||||
// let v1 = Rc::new(TypeVariable(ctx.add_variable(VarDef {
|
Err("unbounded type var".to_string())
|
||||||
// name: "V1",
|
);
|
||||||
// bound: vec![],
|
assert_eq!(
|
||||||
// })));
|
resolve_call(&ctx, Some(v1.clone()), "__add__", &[v0.clone()]),
|
||||||
// let v2 = Rc::new(TypeVariable(ctx.add_variable(VarDef {
|
Err("different domain".to_string())
|
||||||
// name: "V2",
|
);
|
||||||
// bound: vec![],
|
assert_eq!(
|
||||||
// })));
|
resolve_call(&ctx, Some(v1.clone()), "__add__", &[v2.clone()]),
|
||||||
// let v3 = Rc::new(TypeVariable(ctx.add_variable(VarDef {
|
Err("different domain".to_string())
|
||||||
// name: "V3",
|
);
|
||||||
// bound: vec![],
|
assert_eq!(
|
||||||
// })));
|
resolve_call(&ctx, Some(v1.clone()), "__add__", &[v3.clone()]),
|
||||||
|
Err("different domain".to_string())
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
resolve_call(&ctx, Some(v3.clone()), "__add__", &[v1.clone()]),
|
||||||
|
Err("no such function".to_string())
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
resolve_call(&ctx, Some(v3.clone()), "__add__", &[v3.clone()]),
|
||||||
|
Err("no such function".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// ctx.add_fn(
|
#[test]
|
||||||
// "foo",
|
fn test_multi_generic() {
|
||||||
// FnDef {
|
let mut ctx = basic_ctx();
|
||||||
// args: vec![v0.clone(), v0.clone(), v1.clone()],
|
let v0 = ctx.add_variable(VarDef {
|
||||||
// result: Some(v0.clone()),
|
name: "V0",
|
||||||
// },
|
bound: vec![],
|
||||||
// );
|
});
|
||||||
|
let v0 = ctx.get_variable(v0);
|
||||||
|
let v1 = ctx.add_variable(VarDef {
|
||||||
|
name: "V1",
|
||||||
|
bound: vec![],
|
||||||
|
});
|
||||||
|
let v1 = ctx.get_variable(v1);
|
||||||
|
let v2 = ctx.add_variable(VarDef {
|
||||||
|
name: "V2",
|
||||||
|
bound: vec![],
|
||||||
|
});
|
||||||
|
let v2 = ctx.get_variable(v2);
|
||||||
|
let v3 = ctx.add_variable(VarDef {
|
||||||
|
name: "V3",
|
||||||
|
bound: vec![],
|
||||||
|
});
|
||||||
|
let v3 = ctx.get_variable(v3);
|
||||||
|
|
||||||
// ctx.add_fn(
|
ctx.add_fn(
|
||||||
// "foo1",
|
"foo",
|
||||||
// FnDef {
|
FnDef {
|
||||||
// args: vec![
|
args: vec![v0.clone(), v0.clone(), v1.clone()],
|
||||||
// ParametricType(TUPLE_TYPE, vec![v0.clone(), v0.clone(), v1.clone()]).into(),
|
result: Some(v0.clone()),
|
||||||
// ],
|
},
|
||||||
// result: Some(v0.clone()),
|
);
|
||||||
// },
|
|
||||||
// );
|
|
||||||
|
|
||||||
// assert_eq!(
|
ctx.add_fn(
|
||||||
// resolve_call(&ctx, None, "foo", &[v2.clone(), v2.clone(), v2.clone()]),
|
"foo1",
|
||||||
// Ok(Some(v2.clone()))
|
FnDef {
|
||||||
// );
|
args: vec![
|
||||||
// assert_eq!(
|
ParametricType(TUPLE_TYPE, vec![v0.clone(), v0.clone(), v1.clone()]).into(),
|
||||||
// resolve_call(&ctx, None, "foo", &[v2.clone(), v2.clone(), v3.clone()]),
|
],
|
||||||
// Ok(Some(v2.clone()))
|
result: Some(v0.clone()),
|
||||||
// );
|
},
|
||||||
// assert_eq!(
|
);
|
||||||
// resolve_call(&ctx, None, "foo", &[v2.clone(), v3.clone(), v3.clone()]),
|
let ctx = get_inference_context(ctx);
|
||||||
// Err("different variables".to_string())
|
|
||||||
// );
|
|
||||||
|
|
||||||
// assert_eq!(
|
assert_eq!(
|
||||||
// resolve_call(
|
resolve_call(&ctx, None, "foo", &[v2.clone(), v2.clone(), v2.clone()]),
|
||||||
// &ctx,
|
Ok(Some(v2.clone()))
|
||||||
// None,
|
);
|
||||||
// "foo1",
|
assert_eq!(
|
||||||
// &[ParametricType(TUPLE_TYPE, vec![v2.clone(), v2.clone(), v2.clone()]).into()]
|
resolve_call(&ctx, None, "foo", &[v2.clone(), v2.clone(), v3.clone()]),
|
||||||
// ),
|
Ok(Some(v2.clone()))
|
||||||
// Ok(Some(v2.clone()))
|
);
|
||||||
// );
|
assert_eq!(
|
||||||
// assert_eq!(
|
resolve_call(&ctx, None, "foo", &[v2.clone(), v3.clone(), v3.clone()]),
|
||||||
// resolve_call(
|
Err("different variables".to_string())
|
||||||
// &ctx,
|
);
|
||||||
// None,
|
|
||||||
// "foo1",
|
|
||||||
// &[ParametricType(TUPLE_TYPE, vec![v2.clone(), v2.clone(), v3.clone()]).into()]
|
|
||||||
// ),
|
|
||||||
// Ok(Some(v2.clone()))
|
|
||||||
// );
|
|
||||||
// assert_eq!(
|
|
||||||
// resolve_call(
|
|
||||||
// &ctx,
|
|
||||||
// None,
|
|
||||||
// "foo1",
|
|
||||||
// &[ParametricType(TUPLE_TYPE, vec![v2.clone(), v3.clone(), v3.clone()]).into()]
|
|
||||||
// ),
|
|
||||||
// Err("different variables".to_string())
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[test]
|
assert_eq!(
|
||||||
// fn test_class_generics() {
|
resolve_call(
|
||||||
// let mut ctx = basic_ctx();
|
&ctx,
|
||||||
|
None,
|
||||||
|
"foo1",
|
||||||
|
&[ParametricType(TUPLE_TYPE, vec![v2.clone(), v2.clone(), v2.clone()]).into()]
|
||||||
|
),
|
||||||
|
Ok(Some(v2.clone()))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
resolve_call(
|
||||||
|
&ctx,
|
||||||
|
None,
|
||||||
|
"foo1",
|
||||||
|
&[ParametricType(TUPLE_TYPE, vec![v2.clone(), v2.clone(), v3.clone()]).into()]
|
||||||
|
),
|
||||||
|
Ok(Some(v2.clone()))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
resolve_call(
|
||||||
|
&ctx,
|
||||||
|
None,
|
||||||
|
"foo1",
|
||||||
|
&[ParametricType(TUPLE_TYPE, vec![v2.clone(), v3.clone(), v3.clone()]).into()]
|
||||||
|
),
|
||||||
|
Err("different variables".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// let list = ctx.get_parametric_mut(LIST_TYPE);
|
#[test]
|
||||||
// let t = Rc::new(TypeVariable(list.params[0]));
|
fn test_class_generics() {
|
||||||
// list.base.methods.insert(
|
let mut ctx = basic_ctx();
|
||||||
// "head",
|
|
||||||
// FnDef {
|
|
||||||
// args: vec![],
|
|
||||||
// result: Some(t.clone()),
|
|
||||||
// },
|
|
||||||
// );
|
|
||||||
// list.base.methods.insert(
|
|
||||||
// "append",
|
|
||||||
// FnDef {
|
|
||||||
// args: vec![t.clone()],
|
|
||||||
// result: None,
|
|
||||||
// },
|
|
||||||
// );
|
|
||||||
|
|
||||||
// let v0 = Rc::new(TypeVariable(ctx.add_variable(VarDef {
|
let list = ctx.get_parametric_def_mut(LIST_TYPE);
|
||||||
// name: "V0",
|
let t = Rc::new(TypeVariable(list.params[0]));
|
||||||
// bound: vec![],
|
list.base.methods.insert(
|
||||||
// })));
|
"head",
|
||||||
// let v1 = Rc::new(TypeVariable(ctx.add_variable(VarDef {
|
FnDef {
|
||||||
// name: "V1",
|
args: vec![],
|
||||||
// bound: vec![],
|
result: Some(t.clone()),
|
||||||
// })));
|
},
|
||||||
|
);
|
||||||
|
list.base.methods.insert(
|
||||||
|
"append",
|
||||||
|
FnDef {
|
||||||
|
args: vec![t.clone()],
|
||||||
|
result: None,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
// assert_eq!(
|
let v0 = ctx.add_variable(VarDef {
|
||||||
// resolve_call(
|
name: "V0",
|
||||||
// &ctx,
|
bound: vec![],
|
||||||
// Some(ParametricType(LIST_TYPE, vec![v0.clone()]).into()),
|
});
|
||||||
// "head",
|
let v0 = ctx.get_variable(v0);
|
||||||
// &[]
|
let v1 = ctx.add_variable(VarDef {
|
||||||
// ),
|
name: "V1",
|
||||||
// Ok(Some(v0.clone()))
|
bound: vec![],
|
||||||
// );
|
});
|
||||||
// assert_eq!(
|
let v1 = ctx.get_variable(v1);
|
||||||
// resolve_call(
|
let ctx = get_inference_context(ctx);
|
||||||
// &ctx,
|
|
||||||
// Some(ParametricType(LIST_TYPE, vec![v0.clone()]).into()),
|
|
||||||
// "append",
|
|
||||||
// &[v0.clone()]
|
|
||||||
// ),
|
|
||||||
// Ok(None)
|
|
||||||
// );
|
|
||||||
// assert_eq!(
|
|
||||||
// resolve_call(
|
|
||||||
// &ctx,
|
|
||||||
// Some(ParametricType(LIST_TYPE, vec![v0.clone()]).into()),
|
|
||||||
// "append",
|
|
||||||
// &[v1.clone()]
|
|
||||||
// ),
|
|
||||||
// Err("different variables".to_string())
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[test]
|
assert_eq!(
|
||||||
// fn test_virtual_class() {
|
resolve_call(
|
||||||
// let mut ctx = basic_ctx();
|
&ctx,
|
||||||
|
Some(ParametricType(LIST_TYPE, vec![v0.clone()]).into()),
|
||||||
|
"head",
|
||||||
|
&[]
|
||||||
|
),
|
||||||
|
Ok(Some(v0.clone()))
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
resolve_call(
|
||||||
|
&ctx,
|
||||||
|
Some(ParametricType(LIST_TYPE, vec![v0.clone()]).into()),
|
||||||
|
"append",
|
||||||
|
&[v0.clone()]
|
||||||
|
),
|
||||||
|
Ok(None)
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
resolve_call(
|
||||||
|
&ctx,
|
||||||
|
Some(ParametricType(LIST_TYPE, vec![v0.clone()]).into()),
|
||||||
|
"append",
|
||||||
|
&[v1.clone()]
|
||||||
|
),
|
||||||
|
Err("different variables".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// let foo = ctx.add_class(ClassDef {
|
#[test]
|
||||||
// base: TypeDef {
|
fn test_virtual_class() {
|
||||||
// name: "Foo",
|
let mut ctx = basic_ctx();
|
||||||
// methods: HashMap::new(),
|
|
||||||
// fields: HashMap::new(),
|
|
||||||
// },
|
|
||||||
// parents: vec![],
|
|
||||||
// });
|
|
||||||
|
|
||||||
// let foo1 = ctx.add_class(ClassDef {
|
let foo = ctx.add_class(ClassDef {
|
||||||
// base: TypeDef {
|
base: TypeDef {
|
||||||
// name: "Foo1",
|
name: "Foo",
|
||||||
// methods: HashMap::new(),
|
methods: HashMap::new(),
|
||||||
// fields: HashMap::new(),
|
fields: HashMap::new(),
|
||||||
// },
|
},
|
||||||
// parents: vec![foo],
|
parents: vec![],
|
||||||
// });
|
});
|
||||||
|
|
||||||
// let foo2 = ctx.add_class(ClassDef {
|
let foo1 = ctx.add_class(ClassDef {
|
||||||
// base: TypeDef {
|
base: TypeDef {
|
||||||
// name: "Foo2",
|
name: "Foo1",
|
||||||
// methods: HashMap::new(),
|
methods: HashMap::new(),
|
||||||
// fields: HashMap::new(),
|
fields: HashMap::new(),
|
||||||
// },
|
},
|
||||||
// parents: vec![foo1],
|
parents: vec![foo],
|
||||||
// });
|
});
|
||||||
|
|
||||||
// let bar = ctx.add_class(ClassDef {
|
let foo2 = ctx.add_class(ClassDef {
|
||||||
// base: TypeDef {
|
base: TypeDef {
|
||||||
// name: "bar",
|
name: "Foo2",
|
||||||
// methods: HashMap::new(),
|
methods: HashMap::new(),
|
||||||
// fields: HashMap::new(),
|
fields: HashMap::new(),
|
||||||
// },
|
},
|
||||||
// parents: vec![],
|
parents: vec![foo1],
|
||||||
// });
|
});
|
||||||
|
|
||||||
// ctx.add_fn(
|
let bar = ctx.add_class(ClassDef {
|
||||||
// "foo",
|
base: TypeDef {
|
||||||
// FnDef {
|
name: "bar",
|
||||||
// args: vec![VirtualClassType(foo).into()],
|
methods: HashMap::new(),
|
||||||
// result: None,
|
fields: HashMap::new(),
|
||||||
// },
|
},
|
||||||
// );
|
parents: vec![],
|
||||||
// ctx.add_fn(
|
});
|
||||||
// "foo1",
|
|
||||||
// FnDef {
|
|
||||||
// args: vec![VirtualClassType(foo1).into()],
|
|
||||||
// result: None,
|
|
||||||
// },
|
|
||||||
// );
|
|
||||||
|
|
||||||
// assert_eq!(
|
ctx.add_fn(
|
||||||
// resolve_call(&ctx, None, "foo", &[ClassType(foo).into()]),
|
"foo",
|
||||||
// Ok(None)
|
FnDef {
|
||||||
// );
|
args: vec![VirtualClassType(foo).into()],
|
||||||
|
result: None,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
ctx.add_fn(
|
||||||
|
"foo1",
|
||||||
|
FnDef {
|
||||||
|
args: vec![VirtualClassType(foo1).into()],
|
||||||
|
result: None,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
let ctx = get_inference_context(ctx);
|
||||||
|
|
||||||
// assert_eq!(
|
assert_eq!(
|
||||||
// resolve_call(&ctx, None, "foo", &[ClassType(foo1).into()]),
|
resolve_call(&ctx, None, "foo", &[ClassType(foo).into()]),
|
||||||
// Ok(None)
|
Ok(None)
|
||||||
// );
|
);
|
||||||
|
|
||||||
// assert_eq!(
|
assert_eq!(
|
||||||
// resolve_call(&ctx, None, "foo", &[ClassType(foo2).into()]),
|
resolve_call(&ctx, None, "foo", &[ClassType(foo1).into()]),
|
||||||
// Ok(None)
|
Ok(None)
|
||||||
// );
|
);
|
||||||
|
|
||||||
// assert_eq!(
|
assert_eq!(
|
||||||
// resolve_call(&ctx, None, "foo", &[ClassType(bar).into()]),
|
resolve_call(&ctx, None, "foo", &[ClassType(foo2).into()]),
|
||||||
// Err("not subtype".to_string())
|
Ok(None)
|
||||||
// );
|
);
|
||||||
|
|
||||||
// assert_eq!(
|
assert_eq!(
|
||||||
// resolve_call(&ctx, None, "foo1", &[ClassType(foo1).into()]),
|
resolve_call(&ctx, None, "foo", &[ClassType(bar).into()]),
|
||||||
// Ok(None)
|
Err("not subtype".to_string())
|
||||||
// );
|
);
|
||||||
|
|
||||||
// assert_eq!(
|
assert_eq!(
|
||||||
// resolve_call(&ctx, None, "foo1", &[ClassType(foo2).into()]),
|
resolve_call(&ctx, None, "foo1", &[ClassType(foo1).into()]),
|
||||||
// Ok(None)
|
Ok(None)
|
||||||
// );
|
);
|
||||||
|
|
||||||
// assert_eq!(
|
assert_eq!(
|
||||||
// resolve_call(&ctx, None, "foo1", &[ClassType(foo).into()]),
|
resolve_call(&ctx, None, "foo1", &[ClassType(foo2).into()]),
|
||||||
// Err("not subtype".to_string())
|
Ok(None)
|
||||||
// );
|
);
|
||||||
|
|
||||||
// // virtual class substitution
|
assert_eq!(
|
||||||
// assert_eq!(
|
resolve_call(&ctx, None, "foo1", &[ClassType(foo).into()]),
|
||||||
// resolve_call(&ctx, None, "foo", &[VirtualClassType(foo).into()]),
|
Err("not subtype".to_string())
|
||||||
// Ok(None)
|
);
|
||||||
// );
|
|
||||||
// assert_eq!(
|
// virtual class substitution
|
||||||
// resolve_call(&ctx, None, "foo", &[VirtualClassType(foo1).into()]),
|
assert_eq!(
|
||||||
// Ok(None)
|
resolve_call(&ctx, None, "foo", &[VirtualClassType(foo).into()]),
|
||||||
// );
|
Ok(None)
|
||||||
// assert_eq!(
|
);
|
||||||
// resolve_call(&ctx, None, "foo", &[VirtualClassType(foo2).into()]),
|
assert_eq!(
|
||||||
// Ok(None)
|
resolve_call(&ctx, None, "foo", &[VirtualClassType(foo1).into()]),
|
||||||
// );
|
Ok(None)
|
||||||
// assert_eq!(
|
);
|
||||||
// resolve_call(&ctx, None, "foo", &[VirtualClassType(bar).into()]),
|
assert_eq!(
|
||||||
// Err("not subtype".to_string())
|
resolve_call(&ctx, None, "foo", &[VirtualClassType(foo2).into()]),
|
||||||
// );
|
Ok(None)
|
||||||
// }
|
);
|
||||||
// }
|
assert_eq!(
|
||||||
|
resolve_call(&ctx, None, "foo", &[VirtualClassType(bar).into()]),
|
||||||
|
Err("not subtype".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue