forked from M-Labs/nac3
fix rebase conflict and some test failure with unifier's error message
This commit is contained in:
parent
364054331c
commit
fb5b4697a9
@ -56,7 +56,7 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
|||||||
// we cannot have other types, virtual type should be handled by function calls
|
// we cannot have other types, virtual type should be handled by function calls
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
let def = &self.top_level.definitions[obj_id.0];
|
let def = &self.top_level.definitions.read()[obj_id.0];
|
||||||
let index = if let TopLevelDef::Class { fields, .. } = &*def.read() {
|
let index = if let TopLevelDef::Class { fields, .. } = &*def.read() {
|
||||||
fields.iter().find_position(|x| x.0 == attr).unwrap().0
|
fields.iter().find_position(|x| x.0 == attr).unwrap().0
|
||||||
} else {
|
} else {
|
||||||
@ -104,7 +104,8 @@ impl<'ctx, 'a> CodeGenContext<'ctx, 'a> {
|
|||||||
ret: Type,
|
ret: Type,
|
||||||
) -> Option<BasicValueEnum<'ctx>> {
|
) -> Option<BasicValueEnum<'ctx>> {
|
||||||
let key = self.get_subst_key(obj.map(|(a, _)| a), fun.0);
|
let key = self.get_subst_key(obj.map(|(a, _)| a), fun.0);
|
||||||
let definition = self.top_level.definitions.get(fun.1 .0).unwrap();
|
let top_level_defs = self.top_level.definitions.read();
|
||||||
|
let definition = top_level_defs.get(fun.1 .0).unwrap();
|
||||||
let val = if let TopLevelDef::Function { instance_to_symbol, .. } = &*definition.read() {
|
let val = if let TopLevelDef::Function { instance_to_symbol, .. } = &*definition.read() {
|
||||||
let symbol = instance_to_symbol.get(&key).unwrap_or_else(|| {
|
let symbol = instance_to_symbol.get(&key).unwrap_or_else(|| {
|
||||||
// TODO: codegen for function that are not yet generated
|
// TODO: codegen for function that are not yet generated
|
||||||
|
@ -206,7 +206,8 @@ fn get_llvm_type<'ctx>(
|
|||||||
match &*unifier.get_ty(ty) {
|
match &*unifier.get_ty(ty) {
|
||||||
TObj { obj_id, fields, .. } => {
|
TObj { obj_id, fields, .. } => {
|
||||||
// a struct with fields in the order of declaration
|
// a struct with fields in the order of declaration
|
||||||
let definition = top_level.definitions.get(obj_id.0).unwrap();
|
let top_level_defs = top_level.definitions.read();
|
||||||
|
let definition = top_level_defs.get(obj_id.0).unwrap();
|
||||||
let ty = if let TopLevelDef::Class { fields: fields_list, .. } = &*definition.read()
|
let ty = if let TopLevelDef::Class { fields: fields_list, .. } = &*definition.read()
|
||||||
{
|
{
|
||||||
let fields = fields.borrow();
|
let fields = fields.borrow();
|
||||||
|
@ -339,7 +339,7 @@ pub enum TopLevelDef {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct TopLevelContext {
|
pub struct TopLevelContext {
|
||||||
pub definitions: Arc<Vec<Arc<RwLock<TopLevelDef>>>>,
|
pub definitions: Arc<RwLock<Vec<Arc<RwLock<TopLevelDef>>>>>,
|
||||||
pub unifiers: Arc<RwLock<Vec<(SharedUnifier, PrimitiveStore)>>>,
|
pub unifiers: Arc<RwLock<Vec<(SharedUnifier, PrimitiveStore)>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -357,21 +357,15 @@ pub struct TopLevelComposer {
|
|||||||
pub keyword_list: Vec<String>,
|
pub keyword_list: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TopLevelContext {
|
|
||||||
pub fn read_top_level_def_list(&self) -> &[Arc<RwLock<TopLevelDef>>] {
|
|
||||||
self.definitions.as_slice()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TopLevelComposer {
|
impl TopLevelComposer {
|
||||||
pub fn make_top_level_context(self) -> TopLevelContext {
|
pub fn make_top_level_context(self) -> TopLevelContext {
|
||||||
TopLevelContext {
|
TopLevelContext {
|
||||||
definitions: self
|
definitions: RwLock::new(self
|
||||||
.definition_ast_list
|
.definition_ast_list
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|(x, ..)| x)
|
.map(|(x, ..)| x)
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.into(),
|
).into(),
|
||||||
// FIXME: all the big unifier or?
|
// FIXME: all the big unifier or?
|
||||||
unifiers: Default::default(),
|
unifiers: Default::default(),
|
||||||
}
|
}
|
||||||
@ -924,7 +918,8 @@ impl TopLevelComposer {
|
|||||||
fields,
|
fields,
|
||||||
methods,
|
methods,
|
||||||
resolver,
|
resolver,
|
||||||
type_vars
|
type_vars,
|
||||||
|
..
|
||||||
} = class_def.deref_mut() {
|
} = class_def.deref_mut() {
|
||||||
if let ast::StmtKind::ClassDef { name, bases, body, .. } = &class_ast {
|
if let ast::StmtKind::ClassDef { name, bases, body, .. } = &class_ast {
|
||||||
(object_id, name.clone(), bases, body, ancestors, fields, methods, type_vars, resolver)
|
(object_id, name.clone(), bases, body, ancestors, fields, methods, type_vars, resolver)
|
||||||
|
@ -82,8 +82,9 @@ impl<'a> fold::Fold<()> for Inferencer<'a> {
|
|||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
let top_level_defs = self.top_level.definitions.read();
|
||||||
let annotation_type = self.function_data.resolver.parse_type_annotation(
|
let annotation_type = self.function_data.resolver.parse_type_annotation(
|
||||||
self.top_level.read_top_level_def_list(),
|
top_level_defs.as_slice(),
|
||||||
self.unifier,
|
self.unifier,
|
||||||
&self.primitives,
|
&self.primitives,
|
||||||
annotation.as_ref(),
|
annotation.as_ref(),
|
||||||
@ -344,8 +345,9 @@ impl<'a> Inferencer<'a> {
|
|||||||
}
|
}
|
||||||
let arg0 = self.fold_expr(args.remove(0))?;
|
let arg0 = self.fold_expr(args.remove(0))?;
|
||||||
let ty = if let Some(arg) = args.pop() {
|
let ty = if let Some(arg) = args.pop() {
|
||||||
|
let top_level_defs = self.top_level.definitions.read();
|
||||||
self.function_data.resolver.parse_type_annotation(
|
self.function_data.resolver.parse_type_annotation(
|
||||||
self.top_level.read_top_level_def_list(),
|
top_level_defs.as_slice(),
|
||||||
self.unifier,
|
self.unifier,
|
||||||
self.primitives,
|
self.primitives,
|
||||||
&arg,
|
&arg,
|
||||||
|
@ -269,7 +269,7 @@ impl TestEnvironment {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
let top_level = TopLevelContext {
|
let top_level = TopLevelContext {
|
||||||
definitions: Arc::new(top_level_defs),
|
definitions: Arc::new(top_level_defs.into()),
|
||||||
unifiers: Default::default(),
|
unifiers: Default::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -263,7 +263,7 @@ fn test_unify(
|
|||||||
("v1", "Tuple[int]"),
|
("v1", "Tuple[int]"),
|
||||||
("v2", "List[int]"),
|
("v2", "List[int]"),
|
||||||
],
|
],
|
||||||
(("v1", "v2"), "Cannot unify TList with TTuple")
|
(("v1", "v2"), "Cannot unify list[0] with tuple[0]")
|
||||||
; "type mismatch"
|
; "type mismatch"
|
||||||
)]
|
)]
|
||||||
#[test_case(2,
|
#[test_case(2,
|
||||||
@ -271,7 +271,7 @@ fn test_unify(
|
|||||||
("v1", "Tuple[int]"),
|
("v1", "Tuple[int]"),
|
||||||
("v2", "Tuple[float]"),
|
("v2", "Tuple[float]"),
|
||||||
],
|
],
|
||||||
(("v1", "v2"), "Cannot unify objects with ID 0 and 1")
|
(("v1", "v2"), "Cannot unify 0 with 1")
|
||||||
; "tuple parameter mismatch"
|
; "tuple parameter mismatch"
|
||||||
)]
|
)]
|
||||||
#[test_case(2,
|
#[test_case(2,
|
||||||
@ -377,7 +377,7 @@ fn test_typevar_range() {
|
|||||||
let v = env.unifier.get_fresh_var_with_range(&[int, boolean]).0;
|
let v = env.unifier.get_fresh_var_with_range(&[int, boolean]).0;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
env.unifier.unify(int_list, v),
|
env.unifier.unify(int_list, v),
|
||||||
Err("Cannot unify type variable 3 with TList due to incompatible value range".to_string())
|
Err("Cannot unify variable 3 with list[0] due to incompatible value range".to_string())
|
||||||
);
|
);
|
||||||
|
|
||||||
// unification between v and float
|
// unification between v and float
|
||||||
@ -385,7 +385,7 @@ fn test_typevar_range() {
|
|||||||
let v = env.unifier.get_fresh_var_with_range(&[int, boolean]).0;
|
let v = env.unifier.get_fresh_var_with_range(&[int, boolean]).0;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
env.unifier.unify(float, v),
|
env.unifier.unify(float, v),
|
||||||
Err("Cannot unify type variable 4 with TObj due to incompatible value range".to_string())
|
Err("Cannot unify variable 4 with 1 due to incompatible value range".to_string())
|
||||||
);
|
);
|
||||||
|
|
||||||
let v1 = env.unifier.get_fresh_var_with_range(&[int, boolean]).0;
|
let v1 = env.unifier.get_fresh_var_with_range(&[int, boolean]).0;
|
||||||
@ -405,7 +405,7 @@ fn test_typevar_range() {
|
|||||||
// where v in (int, List[v1]), v1 in (int, bool)
|
// where v in (int, List[v1]), v1 in (int, bool)
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
env.unifier.unify(float_list, v),
|
env.unifier.unify(float_list, v),
|
||||||
Err("Cannot unify type variable 8 with TList due to incompatible value range".to_string())
|
Err("Cannot unify variable 8 with list[1] due to incompatible value range".to_string())
|
||||||
);
|
);
|
||||||
|
|
||||||
let a = env.unifier.get_fresh_var_with_range(&[int, float]).0;
|
let a = env.unifier.get_fresh_var_with_range(&[int, float]).0;
|
||||||
@ -418,7 +418,7 @@ fn test_typevar_range() {
|
|||||||
env.unifier.unify(a, b).unwrap();
|
env.unifier.unify(a, b).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
env.unifier.unify(a, int),
|
env.unifier.unify(a, int),
|
||||||
Err("Cannot unify type variable 12 with TObj due to incompatible value range".into())
|
Err("Cannot unify variable 12 with 0 due to incompatible value range".into())
|
||||||
);
|
);
|
||||||
|
|
||||||
let a = env.unifier.get_fresh_var_with_range(&[int, float]).0;
|
let a = env.unifier.get_fresh_var_with_range(&[int, float]).0;
|
||||||
@ -441,7 +441,7 @@ fn test_typevar_range() {
|
|||||||
let int_list = env.unifier.add_ty(TypeEnum::TList { ty: int });
|
let int_list = env.unifier.add_ty(TypeEnum::TList { ty: int });
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
env.unifier.unify(a_list, int_list),
|
env.unifier.unify(a_list, int_list),
|
||||||
Err("Cannot unify type variable 19 with TObj due to incompatible value range".into())
|
Err("Cannot unify variable 19 with 0 due to incompatible value range".into())
|
||||||
);
|
);
|
||||||
|
|
||||||
let a = env.unifier.get_fresh_var_with_range(&[int, float]).0;
|
let a = env.unifier.get_fresh_var_with_range(&[int, float]).0;
|
||||||
@ -452,7 +452,7 @@ fn test_typevar_range() {
|
|||||||
env.unifier.unify(a_list, b_list).unwrap();
|
env.unifier.unify(a_list, b_list).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
env.unifier.unify(b, boolean),
|
env.unifier.unify(b, boolean),
|
||||||
Err("Cannot unify type variable 21 with TObj due to incompatible value range".into())
|
Err("Cannot unify variable 21 with 2 due to incompatible value range".into())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -467,11 +467,11 @@ fn test_rigid_var() {
|
|||||||
let int = env.parse("int", &HashMap::new());
|
let int = env.parse("int", &HashMap::new());
|
||||||
let list_int = env.parse("List[int]", &HashMap::new());
|
let list_int = env.parse("List[int]", &HashMap::new());
|
||||||
|
|
||||||
assert_eq!(env.unifier.unify(a, b), Err("Cannot unify TRigidVar with TRigidVar".to_string()));
|
assert_eq!(env.unifier.unify(a, b), Err("Cannot unify var3 with var2".to_string()));
|
||||||
env.unifier.unify(list_a, list_x).unwrap();
|
env.unifier.unify(list_a, list_x).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
env.unifier.unify(list_x, list_int),
|
env.unifier.unify(list_x, list_int),
|
||||||
Err("Cannot unify TObj with TRigidVar".to_string())
|
Err("Cannot unify 0 with var2".to_string())
|
||||||
);
|
);
|
||||||
|
|
||||||
env.unifier.replace_rigid_var(a, int);
|
env.unifier.replace_rigid_var(a, int);
|
||||||
|
@ -52,8 +52,8 @@ fn main() {
|
|||||||
|
|
||||||
let (_, composer) = TopLevelComposer::new();
|
let (_, composer) = TopLevelComposer::new();
|
||||||
let mut unifier = composer.unifier.clone();
|
let mut unifier = composer.unifier.clone();
|
||||||
let primitives = composer.primitives.clone();
|
let primitives = composer.primitives_ty.clone();
|
||||||
let top_level = Arc::new(composer.to_top_level_context());
|
let top_level = Arc::new(composer.make_top_level_context());
|
||||||
unifier.top_level = Some(top_level.clone());
|
unifier.top_level = Some(top_level.clone());
|
||||||
let fun = unifier.add_ty(TypeEnum::TFunc(RefCell::new(FunSignature {
|
let fun = unifier.add_ty(TypeEnum::TFunc(RefCell::new(FunSignature {
|
||||||
args: vec![FuncArg {
|
args: vec![FuncArg {
|
||||||
|
Loading…
Reference in New Issue
Block a user