nac3artiq: remove cached pyid_to_type if error

This commit is contained in:
ychenfo 2022-03-02 21:39:45 +08:00 committed by Gitea
parent 317eb80005
commit 84b4bd920b
1 changed files with 45 additions and 33 deletions

View File

@ -531,10 +531,13 @@ impl InnerResolver {
} }
(TypeEnum::TObj { params, fields, .. }, false) => { (TypeEnum::TObj { params, fields, .. }, false) => {
self.pyid_to_type.write().insert(ty_id, extracted_ty); self.pyid_to_type.write().insert(ty_id, extracted_ty);
let mut instantiate_obj = || {
let var_map = params let var_map = params
.iter() .iter()
.map(|(id_var, ty)| { .map(|(id_var, ty)| {
if let TypeEnum::TVar { id, range, name, loc, .. } = &*unifier.get_ty(*ty) { if let TypeEnum::TVar { id, range, name, loc, .. } =
&*unifier.get_ty(*ty)
{
assert_eq!(*id, *id_var); assert_eq!(*id, *id_var);
(*id, unifier.get_fresh_var_with_range(range, *name, *loc).0) (*id, unifier.get_fresh_var_with_range(range, *name, *loc).0)
} else { } else {
@ -549,8 +552,9 @@ impl InnerResolver {
continue; continue;
} else { } else {
let field_data = obj.getattr(&name)?; let field_data = obj.getattr(&name)?;
let ty = let ty = match self
match self.get_obj_type(py, field_data, unifier, defs, primitives)? { .get_obj_type(py, field_data, unifier, defs, primitives)?
{
Ok(t) => t, Ok(t) => t,
Err(e) => { Err(e) => {
return Ok(Err(format!( return Ok(Err(format!(
@ -559,7 +563,8 @@ impl InnerResolver {
))) )))
} }
}; };
let field_ty = unifier.subst(field.1 .0, &var_map).unwrap_or(field.1 .0); let field_ty =
unifier.subst(field.1 .0, &var_map).unwrap_or(field.1 .0);
if let Err(e) = unifier.unify(ty, field_ty) { if let Err(e) = unifier.unify(ty, field_ty) {
// field type mismatch // field type mismatch
return Ok(Err(format!( return Ok(Err(format!(
@ -576,7 +581,14 @@ impl InnerResolver {
return Ok(Err("object is not of concrete type".into())); return Ok(Err("object is not of concrete type".into()));
} }
} }
return Ok(Ok(unifier.subst(extracted_ty, &var_map).unwrap_or(extracted_ty))); Ok(Ok(unifier.subst(extracted_ty, &var_map).unwrap_or(extracted_ty)))
};
let result = instantiate_obj();
// do not cache the type if there are errors
if matches!(result, Err(_) | Ok(Err(_))) {
self.pyid_to_type.write().remove(&ty_id);
}
result
} }
_ => Ok(Ok(extracted_ty)), _ => Ok(Ok(extracted_ty)),
}; };