nac3artiq: host object supports typevar

This commit is contained in:
pca006132 2021-10-08 22:43:23 +08:00
parent c5bcd352a5
commit a07674a042
1 changed files with 40 additions and 25 deletions

View File

@ -120,7 +120,19 @@ impl Resolver {
.. ..
} = &*def } = &*def
{ {
if type_vars.is_empty() { let var_map: HashMap<_, _> = type_vars
.iter()
.map(|var| {
(
if let TypeEnum::TVar { id, .. } = &*unifier.get_ty(*var) {
*id
} else {
unreachable!()
},
unifier.get_fresh_var().0,
)
})
.collect();
let mut fields_ty = HashMap::new(); let mut fields_ty = HashMap::new();
for method in methods.iter() { for method in methods.iter() {
fields_ty.insert(method.0, method.1); fields_ty.insert(method.0, method.1);
@ -131,21 +143,24 @@ impl Resolver {
let ty = self let ty = self
.get_obj_type(field_data, helper, unifier, defs, primitives)? .get_obj_type(field_data, helper, unifier, defs, primitives)?
.unwrap_or(primitives.none); .unwrap_or(primitives.none);
if unifier.unify(ty, field.1).is_err() { let field_ty = unifier.subst(field.1, &var_map).unwrap_or(field.1);
if unifier.unify(ty, field_ty).is_err() {
// field type mismatch // field type mismatch
return Ok(None); return Ok(None);
} }
fields_ty.insert(field.0, ty); fields_ty.insert(field.0, ty);
} }
for (_, ty) in var_map.iter() {
// must be concrete type
if !unifier.is_concrete(*ty, &[]) {
return Ok(None)
}
}
Ok(Some(unifier.add_ty(TypeEnum::TObj { Ok(Some(unifier.add_ty(TypeEnum::TObj {
obj_id: *object_id, obj_id: *object_id,
fields: RefCell::new(fields_ty), fields: RefCell::new(fields_ty),
params: Default::default(), params: RefCell::new(var_map),
}))) })))
} else {
// type var is not supported for now
Ok(None)
}
} else { } else {
// only object is supported, functions are not supported // only object is supported, functions are not supported
Ok(None) Ok(None)