forked from M-Labs/nac3
1
0
Fork 0

fix rebase conflict and some test failure with unifier's error message

This commit is contained in:
ychenfo 2021-08-23 10:34:11 +08:00
parent 364054331c
commit fb5b4697a9
7 changed files with 27 additions and 28 deletions

View File

@ -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

View File

@ -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();

View File

@ -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)

View File

@ -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,

View File

@ -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(),
}; };

View File

@ -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);

View File

@ -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 {