From f2dc1814e0c08f762d8eb3152288d01873eeebc6 Mon Sep 17 00:00:00 2001 From: David Mak Date: Fri, 5 Jul 2024 16:46:51 +0800 Subject: [PATCH] artiq: Remove all uses to gil-refs APIs --- nac3artiq/Cargo.toml | 2 +- nac3artiq/src/codegen.rs | 10 +- nac3artiq/src/lib.rs | 87 ++++++------- nac3artiq/src/symbol_resolver.rs | 201 +++++++++++++++++++------------ 4 files changed, 176 insertions(+), 124 deletions(-) diff --git a/nac3artiq/Cargo.toml b/nac3artiq/Cargo.toml index 4e391e1b..26cd2a7c 100644 --- a/nac3artiq/Cargo.toml +++ b/nac3artiq/Cargo.toml @@ -10,7 +10,7 @@ crate-type = ["cdylib"] [dependencies] itertools = "0.13" -pyo3 = { version = "0.22", features = ["extension-module", "gil-refs", "py-clone"] } +pyo3 = { version = "0.22", features = ["extension-module", "py-clone"] } parking_lot = "0.12" tempfile = "3.10" nac3parser = { path = "../nac3parser" } diff --git a/nac3artiq/src/codegen.rs b/nac3artiq/src/codegen.rs index e38f9068..b84135fc 100644 --- a/nac3artiq/src/codegen.rs +++ b/nac3artiq/src/codegen.rs @@ -635,7 +635,7 @@ pub fn attributes_writeback( let val = val.bind_borrowed(py); let ty = inner_resolver.get_obj_type( py, - val.as_gil_ref(), + val, &mut ctx.unifier, &top_levels, &ctx.primitives, @@ -651,9 +651,7 @@ pub fn attributes_writeback( // we only care about primitive attributes // for non-primitive attributes, they should be in another global let mut attributes = Vec::new(); - let obj = inner_resolver - .get_obj_value(py, val.as_gil_ref(), ctx, generator, ty)? - .unwrap(); + let obj = inner_resolver.get_obj_value(py, val, ctx, generator, ty)?.unwrap(); for (name, (field_ty, is_mutable)) in fields { if !is_mutable { continue; @@ -687,9 +685,7 @@ pub fn attributes_writeback( host_attributes.append(pydict)?; values.push(( ty, - inner_resolver - .get_obj_value(py, val.as_gil_ref(), ctx, generator, ty)? - .unwrap(), + inner_resolver.get_obj_value(py, val, ctx, generator, ty)?.unwrap(), )); } } diff --git a/nac3artiq/src/lib.rs b/nac3artiq/src/lib.rs index e967064c..ce09cbd5 100644 --- a/nac3artiq/src/lib.rs +++ b/nac3artiq/src/lib.rs @@ -142,10 +142,6 @@ struct Nac3 { create_exception!(nac3artiq, CompileError, exceptions::PyException); -unsafe impl PyNativeType for CompileError { - type AsRefSource = CompileError; -} - impl Nac3 { fn register_module( &mut self, @@ -153,7 +149,7 @@ impl Nac3 { registered_class_ids: &HashSet, ) -> PyResult<()> { let (module_name, source_file) = Python::with_gil(|py| -> PyResult<(String, String)> { - let module: &PyAny = module.extract(py)?; + let module = module.bind_borrowed(py); Ok((module.getattr("__name__")?.extract()?, module.getattr("__file__")?.extract()?)) })?; @@ -179,14 +175,14 @@ impl Nac3 { // Drop unregistered (i.e. host-only) base classes. bases.retain(|base| { Python::with_gil(|py| -> PyResult { + let module = module.bind_borrowed(py); let id_fn = PyModule::import_bound(py, "builtins")?.getattr("id")?; match &base.node { ExprKind::Name { id, .. } => { if *id == "Exception".into() { Ok(true) } else { - let base_obj = - module.getattr(py, id.to_string().as_str())?; + let base_obj = module.getattr(id.to_string().as_str())?; let base_id = id_fn.call1((base_obj,))?.extract()?; Ok(registered_class_ids.contains(&base_id)) } @@ -310,7 +306,7 @@ impl Nac3 { &self, obj: &Bound, method_name: &str, - args: Vec<&PyAny>, + args: Vec>, embedding_map: &Bound, py: Python, link_fn: &dyn Fn(&Module) -> PyResult, @@ -361,13 +357,17 @@ impl Nac3 { let mut rpc_ids = vec![]; for (stmt, path, module) in &self.top_levels { - let py_module: &PyAny = module.extract(py)?; + let py_module = module.bind_borrowed(py); let module_id: u64 = id_fn.call1((py_module,))?.extract()?; let helper = helper.clone(); let class_obj; if let StmtKind::ClassDef { name, .. } = &stmt.node { let class = py_module.getattr(name.to_string().as_str()).unwrap(); - if issubclass.call1((class, exn_class.as_gil_ref())).unwrap().extract().unwrap() + if issubclass + .call1((class.as_borrowed(), exn_class.as_borrowed())) + .unwrap() + .extract() + .unwrap() && class.getattr("artiq_builtin").is_err() { class_obj = Some(class); @@ -380,8 +380,8 @@ impl Nac3 { let (name_to_pyid, resolver) = module_to_resolver_cache.get(&module_id).cloned().unwrap_or_else(|| { let mut name_to_pyid: HashMap = HashMap::new(); - let members: &PyDict = - py_module.getattr("__dict__").unwrap().downcast().unwrap(); + let members = py_module.getattr("__dict__").unwrap(); + let members = members.downcast::().unwrap(); for (key, val) in members { let key: &str = key.extract().unwrap(); let val = id_fn.call1((val,)).unwrap().extract().unwrap(); @@ -468,7 +468,7 @@ impl Nac3 { let mut arg_names = vec![]; for (i, arg) in args.into_iter().enumerate() { let name = format!("tmp{i}"); - module.add(&*name, arg)?; + module.add(&*name, arg.clone())?; name_to_pyid.insert(name.clone().into(), id_fun.call1((arg,))?.extract()?); arg_names.push(name); } @@ -908,39 +908,44 @@ impl Nac3 { let typing_mod = PyModule::import_bound(py, "typing").unwrap(); let types_mod = PyModule::import_bound(py, "types").unwrap(); - let get_id = |x: &PyAny| id_fn.call1((x,)).and_then(|id| id.extract()).unwrap(); - let get_attr_id = |obj: &PyModule, attr| { + let get_id = |x: Borrowed| id_fn.call1((x,)).and_then(|id| id.extract()).unwrap(); + let get_attr_id = |obj: Borrowed, attr| { id_fn.call1((obj.getattr(attr).unwrap(),)).unwrap().extract().unwrap() }; let primitive_ids = PrimitivePythonId { virtual_id: get_id( - artiq_builtins.get_item("virtual").ok().flatten().unwrap().as_gil_ref(), + artiq_builtins.get_item("virtual").ok().flatten().unwrap().as_borrowed(), ), generic_alias: ( - get_attr_id(typing_mod.as_gil_ref(), "_GenericAlias"), - get_attr_id(types_mod.as_gil_ref(), "GenericAlias"), + get_attr_id(typing_mod.as_borrowed(), "_GenericAlias"), + get_attr_id(types_mod.as_borrowed(), "GenericAlias"), ), - none: get_id(artiq_builtins.get_item("none").ok().flatten().unwrap().as_gil_ref()), - typevar: get_attr_id(typing_mod.as_gil_ref(), "TypeVar"), + none: get_id(artiq_builtins.get_item("none").ok().flatten().unwrap().as_borrowed()), + typevar: get_attr_id(typing_mod.as_borrowed(), "TypeVar"), const_generic_marker: get_id( - artiq_builtins.get_item("_ConstGenericMarker").ok().flatten().unwrap().as_gil_ref(), + artiq_builtins + .get_item("_ConstGenericMarker") + .ok() + .flatten() + .unwrap() + .as_borrowed(), ), - int: get_attr_id(builtins_mod.as_gil_ref(), "int"), - int32: get_attr_id(numpy_mod.as_gil_ref(), "int32"), - int64: get_attr_id(numpy_mod.as_gil_ref(), "int64"), - uint32: get_attr_id(numpy_mod.as_gil_ref(), "uint32"), - uint64: get_attr_id(numpy_mod.as_gil_ref(), "uint64"), - bool: get_attr_id(builtins_mod.as_gil_ref(), "bool"), - np_bool_: get_attr_id(numpy_mod.as_gil_ref(), "bool_"), - string: get_attr_id(builtins_mod.as_gil_ref(), "str"), - np_str_: get_attr_id(numpy_mod.as_gil_ref(), "str_"), - float: get_attr_id(builtins_mod.as_gil_ref(), "float"), - float64: get_attr_id(numpy_mod.as_gil_ref(), "float64"), - list: get_attr_id(builtins_mod.as_gil_ref(), "list"), - ndarray: get_attr_id(numpy_mod.as_gil_ref(), "ndarray"), - tuple: get_attr_id(builtins_mod.as_gil_ref(), "tuple"), - exception: get_attr_id(builtins_mod.as_gil_ref(), "Exception"), - option: get_id(artiq_builtins.get_item("Option").ok().flatten().unwrap().as_gil_ref()), + int: get_attr_id(builtins_mod.as_borrowed(), "int"), + int32: get_attr_id(numpy_mod.as_borrowed(), "int32"), + int64: get_attr_id(numpy_mod.as_borrowed(), "int64"), + uint32: get_attr_id(numpy_mod.as_borrowed(), "uint32"), + uint64: get_attr_id(numpy_mod.as_borrowed(), "uint64"), + bool: get_attr_id(builtins_mod.as_borrowed(), "bool"), + np_bool_: get_attr_id(numpy_mod.as_borrowed(), "bool_"), + string: get_attr_id(builtins_mod.as_borrowed(), "str"), + np_str_: get_attr_id(numpy_mod.as_borrowed(), "str_"), + float: get_attr_id(builtins_mod.as_borrowed(), "float"), + float64: get_attr_id(numpy_mod.as_borrowed(), "float64"), + list: get_attr_id(builtins_mod.as_borrowed(), "list"), + ndarray: get_attr_id(numpy_mod.as_borrowed(), "ndarray"), + tuple: get_attr_id(builtins_mod.as_borrowed(), "tuple"), + exception: get_attr_id(builtins_mod.as_borrowed(), "Exception"), + option: get_id(artiq_builtins.get_item("Option").ok().flatten().unwrap().as_borrowed()), }; let working_directory = tempfile::Builder::new().prefix("nac3-").tempdir().unwrap(); @@ -979,9 +984,9 @@ impl Nac3 { modules.insert(id_fn.call1((&module,))?.extract()?, module); } for class in classes { - let module = getmodule_fn.call1((class.as_gil_ref(),))?.extract()?; + let module = getmodule_fn.call1((class.as_borrowed(),))?.extract()?; modules.insert(id_fn.call1((&module,))?.extract()?, module); - class_ids.insert(id_fn.call1((class.as_gil_ref(),))?.extract()?); + class_ids.insert(id_fn.call1((class,))?.extract()?); } Ok((modules, class_ids)) })?; @@ -996,7 +1001,7 @@ impl Nac3 { &mut self, obj: &Bound, method_name: &str, - args: Vec<&PyAny>, + args: Vec>, filename: &str, embedding_map: &Bound, py: Python, @@ -1042,7 +1047,7 @@ impl Nac3 { &mut self, obj: &Bound, method_name: &str, - args: Vec<&PyAny>, + args: Vec>, embedding_map: &Bound, py: Python, ) -> PyResult { diff --git a/nac3artiq/src/symbol_resolver.rs b/nac3artiq/src/symbol_resolver.rs index b1472132..bbc2761b 100644 --- a/nac3artiq/src/symbol_resolver.rs +++ b/nac3artiq/src/symbol_resolver.rs @@ -171,7 +171,7 @@ impl StaticValue for PythonValue { Python::with_gil(|py| -> PyResult> { self.resolver - .get_obj_value(py, self.value.bind(py).as_gil_ref(), ctx, generator, expected_ty) + .get_obj_value(py, self.value.bind_borrowed(py), ctx, generator, expected_ty) .map(Option::unwrap) }) .map_err(|e| e.to_string()) @@ -240,10 +240,10 @@ impl StaticValue for PythonValue { let ty = helper.type_fn.call1(py, (&self.value,))?; let ty_id: u64 = helper.id_fn.call1(py, (ty,))?.extract(py)?; assert_eq!(ty_id, self.resolver.primitive_ids.tuple); - let tup: &PyTuple = self.value.extract(py)?; + let tup = self.value.downcast_bound::(py)?; let elem = tup.get_item(index as usize)?; - let id = self.resolver.helper.id_fn.call1(py, (elem,))?.extract(py)?; - Ok(Some((id, elem.into()))) + let id = self.resolver.helper.id_fn.call1(py, (elem.as_borrowed(),))?.extract(py)?; + Ok(Some((id, elem.unbind()))) }) .unwrap() .map(|(id, obj)| { @@ -261,21 +261,26 @@ impl InnerResolver { fn get_list_elem_type( &self, py: Python, - list: &PyAny, + list: Borrowed, len: usize, unifier: &mut Unifier, defs: &[Arc>], primitives: &PrimitiveStore, ) -> PyResult> { - let mut ty = match self.get_obj_type(py, list.get_item(0)?, unifier, defs, primitives)? { + let mut ty = match self.get_obj_type( + py, + list.get_item(0)?.as_borrowed(), + unifier, + defs, + primitives, + )? { Ok(t) => t, Err(e) => return Ok(Err(format!("type error ({e}) at element #0 of the list"))), }; for i in 1..len { - let b = match list - .get_item(i) - .map(|elem| self.get_obj_type(py, elem, unifier, defs, primitives))?? - { + let b = match list.get_item(i).map(|elem| { + self.get_obj_type(py, elem.as_borrowed(), unifier, defs, primitives) + })?? { Ok(t) => t, Err(e) => return Ok(Err(format!("type error ({e}) at element #{i} of the list"))), }; @@ -301,7 +306,7 @@ impl InnerResolver { fn get_pyty_obj_type( &self, py: Python, - pyty: &PyAny, + pyty: Borrowed, unifier: &mut Unifier, defs: &[Arc>], primitives: &PrimitiveStore, @@ -389,7 +394,8 @@ impl InnerResolver { (unifier.add_ty(ty), false) })) } else if ty_ty_id == self.primitive_ids.typevar { - let name: &str = pyty.getattr("__name__").unwrap().extract().unwrap(); + let name = pyty.getattr("__name__").unwrap(); + let name: &str = name.extract().unwrap(); let (constraint_types, is_const_generic) = { let constraints = pyty.getattr("__constraints__").unwrap(); let mut result: Vec = vec![]; @@ -398,7 +404,8 @@ impl InnerResolver { let mut is_const_generic = false; for i in 0usize.. { if let Ok(constr) = constraints.get_item(i) { - let constr_id: u64 = self.helper.id_fn.call1(py, (constr,))?.extract(py)?; + let constr_id: u64 = + self.helper.id_fn.call1(py, (constr.as_borrowed(),))?.extract(py)?; if constr_id == self.primitive_ids.const_generic_marker { is_const_generic = true; continue; @@ -408,7 +415,7 @@ impl InnerResolver { result.push(unifier.get_dummy_var().ty); } else { result.push({ - match self.get_pyty_obj_type(py, constr, unifier, defs, primitives)? { + match self.get_pyty_obj_type(py, constr.as_borrowed(), unifier, defs, primitives)? { Ok((ty, _)) => { if unifier.is_concrete(ty, &[]) { ty @@ -462,7 +469,7 @@ impl InnerResolver { let args = args.downcast_bound::(py)?; let origin_ty = match self.get_pyty_obj_type( py, - origin.bind(py).as_gil_ref(), + origin.bind_borrowed(py), unifier, defs, primitives, @@ -479,7 +486,7 @@ impl InnerResolver { if args.len() == 1 { let ty = match self.get_pyty_obj_type( py, - args.get_item(0)?.as_gil_ref(), + args.get_item(0)?.as_borrowed(), unifier, defs, primitives, @@ -529,7 +536,7 @@ impl InnerResolver { let ty = match self.get_pyty_obj_type( py, - dtype.as_gil_ref(), + dtype.as_borrowed(), unifier, defs, primitives, @@ -549,7 +556,7 @@ impl InnerResolver { TypeEnum::TTuple { .. } => { let args = match args .iter() - .map(|x| self.get_pyty_obj_type(py, x.as_gil_ref(), unifier, defs, primitives)) + .map(|x| self.get_pyty_obj_type(py, x.as_borrowed(), unifier, defs, primitives)) .collect::, _>>()? .into_iter() .collect::, _>>() { @@ -579,7 +586,7 @@ impl InnerResolver { } let args = match args .iter() - .map(|x| self.get_pyty_obj_type(py, x.as_gil_ref(), unifier, defs, primitives)) + .map(|x| self.get_pyty_obj_type(py, x.as_borrowed(), unifier, defs, primitives)) .collect::, _>>()? .into_iter() .collect::, _>>() { @@ -606,7 +613,7 @@ impl InnerResolver { if args.len() == 1 { let ty = match self.get_pyty_obj_type( py, - args.get_item(0)?.as_gil_ref(), + args.get_item(0)?.as_borrowed(), unifier, defs, primitives, @@ -646,7 +653,7 @@ impl InnerResolver { pub fn get_obj_type( &self, py: Python, - obj: &PyAny, + obj: Borrowed, unifier: &mut Unifier, defs: &[Arc>], primitives: &PrimitiveStore, @@ -693,7 +700,7 @@ impl InnerResolver { { obj } else { - ty.bind(py).as_gil_ref() + ty.bind_borrowed(py) } }, unifier, @@ -781,7 +788,8 @@ impl InnerResolver { Ok(Ok(extracted_ty)) } else { let dtype = obj.getattr("dtype")?.getattr("type")?; - let dtype_ty = self.get_pyty_obj_type(py, dtype, unifier, defs, primitives)?; + let dtype_ty = + self.get_pyty_obj_type(py, dtype.as_borrowed(), unifier, defs, primitives)?; match dtype_ty { Ok((t, _)) => match unifier.unify(ty, t) { Ok(()) => { @@ -800,10 +808,12 @@ impl InnerResolver { } } (TypeEnum::TTuple { .. }, false) => { - let elements: &PyTuple = obj.downcast()?; + let elements = obj.downcast::()?; let types: Result, _>, _> = elements .iter() - .map(|elem| self.get_obj_type(py, elem, unifier, defs, primitives)) + .map(|elem| { + self.get_obj_type(py, elem.as_borrowed(), unifier, defs, primitives) + }) .collect(); let types = types?; Ok(types.map(|types| unifier.add_ty(TypeEnum::TTuple { ty: types }))) @@ -837,7 +847,13 @@ impl InnerResolver { return Ok(Ok(unifier.subst(primitives.option, &var_map).unwrap())); } - let ty = match self.get_obj_type(py, field_data, unifier, defs, primitives)? { + let ty = match self.get_obj_type( + py, + field_data.as_borrowed(), + unifier, + defs, + primitives, + )? { Ok(t) => t, Err(e) => { return Ok(Err(format!( @@ -872,15 +888,20 @@ impl InnerResolver { Ok(d) => d, Err(e) => return Ok(Err(format!("{e}"))), }; - let ty = - match self.get_obj_type(py, field_data, unifier, defs, primitives)? { - Ok(t) => t, - Err(e) => { - return Ok(Err(format!( - "error when getting type of field `{name}` ({e})" - ))) - } - }; + let ty = match self.get_obj_type( + py, + field_data.as_borrowed(), + unifier, + defs, + primitives, + )? { + Ok(t) => t, + Err(e) => { + return Ok(Err(format!( + "error when getting type of field `{name}` ({e})" + ))) + } + }; let field_ty = unifier.subst(field.1 .0, &var_map).unwrap_or(field.1 .0); if let Err(e) = unifier.unify(ty, field_ty) { // field type mismatch @@ -912,32 +933,32 @@ impl InnerResolver { // check integer bounds if unifier.unioned(extracted_ty, primitives.int32) { obj.extract::().map_or_else( - |_| Ok(Err(format!("{obj} is not in the range of int32"))), + |_| Ok(Err(format!("{} is not in the range of int32", obj.as_unbound()))), |_| Ok(Ok(extracted_ty)), ) } else if unifier.unioned(extracted_ty, primitives.int64) { obj.extract::().map_or_else( - |_| Ok(Err(format!("{obj} is not in the range of int64"))), + |_| Ok(Err(format!("{} is not in the range of int64", obj.as_unbound()))), |_| Ok(Ok(extracted_ty)), ) } else if unifier.unioned(extracted_ty, primitives.uint32) { obj.extract::().map_or_else( - |_| Ok(Err(format!("{obj} is not in the range of uint32"))), + |_| Ok(Err(format!("{} is not in the range of uint32", obj.as_unbound()))), |_| Ok(Ok(extracted_ty)), ) } else if unifier.unioned(extracted_ty, primitives.uint64) { obj.extract::().map_or_else( - |_| Ok(Err(format!("{obj} is not in the range of uint64"))), + |_| Ok(Err(format!("{} is not in the range of uint64", obj.as_unbound()))), |_| Ok(Ok(extracted_ty)), ) } else if unifier.unioned(extracted_ty, primitives.bool) { obj.extract::().map_or_else( - |_| Ok(Err(format!("{obj} is not in the range of bool"))), + |_| Ok(Err(format!("{} is not in the range of bool", obj.as_unbound()))), |_| Ok(Ok(extracted_ty)), ) } else if unifier.unioned(extracted_ty, primitives.float) { obj.extract::().map_or_else( - |_| Ok(Err(format!("{obj} is not in the range of float64"))), + |_| Ok(Err(format!("{} is not in the range of float64", obj.as_unbound()))), |_| Ok(Ok(extracted_ty)), ) } else { @@ -950,7 +971,7 @@ impl InnerResolver { pub fn get_obj_value<'ctx>( &self, py: Python, - obj: &PyAny, + obj: Borrowed, ctx: &mut CodeGenContext<'ctx, '_>, generator: &mut dyn CodeGenerator, expected_ty: Type, @@ -1013,15 +1034,19 @@ impl InnerResolver { }); return Ok(Some(global.as_pointer_value().into())); } - self.global_value_ids.write().insert(id, obj.into()); + self.global_value_ids.write().insert(id, obj.as_unbound().clone()); } let arr: Result>, _> = (0..len) .map(|i| { obj.get_item(i).and_then(|elem| { - self.get_obj_value(py, elem, ctx, generator, elem_ty).map_err(|e| { - super::CompileError::new_err(format!("Error getting element {i}: {e}")) - }) + self.get_obj_value(py, elem.as_borrowed(), ctx, generator, elem_ty).map_err( + |e| { + super::CompileError::new_err(format!( + "Error getting element {i}: {e}" + )) + }, + ) }) }) .collect(); @@ -1096,7 +1121,7 @@ impl InnerResolver { }); return Ok(Some(global.as_pointer_value().into())); } - self.global_value_ids.write().insert(id, obj.into()); + self.global_value_ids.write().insert(id, obj.as_unbound().clone()); } let TypeEnum::TLiteral { values, .. } = &*ctx.unifier.get_ty_immutable(ndarray_ndims) @@ -1114,15 +1139,23 @@ impl InnerResolver { }; // Obtain the shape of the ndarray - let shape_tuple: &PyTuple = obj.getattr("shape")?.downcast()?; + let shape_tuple = obj.getattr("shape")?; + let shape_tuple = shape_tuple.downcast::()?; assert_eq!(shape_tuple.len(), ndarray_ndims as usize); let shape_values: Result>, _> = shape_tuple .iter() .enumerate() .map(|(i, elem)| { - self.get_obj_value(py, elem, ctx, generator, ctx.primitives.usize()).map_err( - |e| super::CompileError::new_err(format!("Error getting element {i}: {e}")), + self.get_obj_value( + py, + elem.as_borrowed(), + ctx, + generator, + ctx.primitives.usize(), ) + .map_err(|e| { + super::CompileError::new_err(format!("Error getting element {i}: {e}")) + }) }) .collect(); let shape_values = shape_values?.unwrap(); @@ -1143,9 +1176,12 @@ impl InnerResolver { let data: Result>, _> = (0..sz) .map(|i| { obj.getattr("flat")?.get_item(i).and_then(|elem| { - self.get_obj_value(py, elem, ctx, generator, ndarray_dtype).map_err(|e| { - super::CompileError::new_err(format!("Error getting element {i}: {e}")) - }) + self.get_obj_value(py, elem.as_borrowed(), ctx, generator, ndarray_dtype) + .map_err(|e| { + super::CompileError::new_err(format!( + "Error getting element {i}: {e}" + )) + }) }) }) .collect(); @@ -1208,14 +1244,14 @@ impl InnerResolver { let TypeEnum::TTuple { ty } = expected_ty_enum.as_ref() else { unreachable!() }; let tup_tys = ty.iter(); - let elements: &PyTuple = obj.downcast()?; + let elements = obj.downcast::()?; assert_eq!(elements.len(), tup_tys.len()); let val: Result>, _> = elements .iter() .enumerate() .zip(tup_tys) .map(|((i, elem), ty)| { - self.get_obj_value(py, elem, ctx, generator, *ty).map_err(|e| { + self.get_obj_value(py, elem.as_borrowed(), ctx, generator, *ty).map_err(|e| { super::CompileError::new_err(format!("Error getting element {i}: {e}")) }) }) @@ -1244,7 +1280,7 @@ impl InnerResolver { match self .get_obj_value( py, - obj.getattr("_nac3_option").unwrap(), + obj.getattr("_nac3_option").unwrap().as_borrowed(), ctx, generator, option_val_ty, @@ -1268,7 +1304,7 @@ impl InnerResolver { }); return Ok(Some(global.as_pointer_value().into())); } - self.global_value_ids.write().insert(id, obj.into()); + self.global_value_ids.write().insert(id, obj.as_unbound().clone()); } let global = ctx.module.add_global( v.get_type(), @@ -1304,7 +1340,7 @@ impl InnerResolver { }); return Ok(Some(global.as_pointer_value().into())); } - self.global_value_ids.write().insert(id, obj.into()); + self.global_value_ids.write().insert(id, obj.as_unbound().clone()); } // should be classes let definition = @@ -1316,7 +1352,7 @@ impl InnerResolver { .map(|(name, ty, _)| { self.get_obj_value( py, - obj.getattr(name.to_string().as_str())?, + obj.getattr(name.to_string().as_str())?.as_borrowed(), ctx, generator, *ty, @@ -1343,7 +1379,7 @@ impl InnerResolver { fn get_default_param_obj_value( &self, py: Python, - obj: &PyAny, + obj: Borrowed, ) -> PyResult> { let id: u64 = self.helper.id_fn.call1(py, (obj,))?.extract(py)?; let ty_id: u64 = @@ -1370,16 +1406,21 @@ impl InnerResolver { let val: f64 = obj.extract()?; Ok(SymbolValue::Double(val)) } else if ty_id == self.primitive_ids.tuple { - let elements: &PyTuple = obj.downcast()?; - let elements: Result, String>, _> = - elements.iter().map(|elem| self.get_default_param_obj_value(py, elem)).collect(); + let elements = obj.downcast::()?; + let elements: Result, String>, _> = elements + .iter() + .map(|elem| self.get_default_param_obj_value(py, elem.as_borrowed())) + .collect(); elements?.map(SymbolValue::Tuple) } else if ty_id == self.primitive_ids.option { if id == self.primitive_ids.none { Ok(SymbolValue::OptionNone) } else { - self.get_default_param_obj_value(py, obj.getattr("_nac3_option").unwrap())? - .map(|v| SymbolValue::OptionSome(Box::new(v))) + self.get_default_param_obj_value( + py, + obj.getattr("_nac3_option").unwrap().as_borrowed(), + )? + .map(|v| SymbolValue::OptionSome(Box::new(v))) } } else { Err("only primitives values, option and tuple can be default parameter value".into()) @@ -1394,13 +1435,14 @@ impl SymbolResolver for Resolver { }; Python::with_gil(|py| -> PyResult> { - let obj: &PyAny = self.0.module.extract(py)?; - let members: &PyDict = obj.getattr("__dict__").unwrap().downcast().unwrap(); + let obj = self.0.module.downcast_bound::(py)?; + let members = obj.getattr("__dict__").unwrap(); + let members = members.downcast::().unwrap(); let mut sym_value = None; for (key, val) in members { let key: &str = key.extract()?; if key == id.to_string() { - if let Ok(Ok(v)) = self.0.get_default_param_obj_value(py, val) { + if let Ok(Ok(v)) = self.0.get_default_param_obj_value(py, val.as_borrowed()) { sym_value = Some(v); } break; @@ -1434,13 +1476,20 @@ impl SymbolResolver for Resolver { Ok(t) } else { Python::with_gil(|py| -> PyResult> { - let obj: &PyAny = self.0.module.extract(py)?; + let obj = self.0.module.downcast_bound::(py)?; let mut sym_ty = Err(format!("cannot find symbol `{str}`")); - let members: &PyDict = obj.getattr("__dict__").unwrap().downcast().unwrap(); + let members = obj.getattr("__dict__").unwrap(); + let members = members.downcast::().unwrap(); for (key, val) in members { let key: &str = key.extract()?; if key == str.to_string() { - sym_ty = self.0.get_obj_type(py, val, unifier, defs, primitives)?; + sym_ty = self.0.get_obj_type( + py, + val.as_borrowed(), + unifier, + defs, + primitives, + )?; break; } } @@ -1468,13 +1517,15 @@ impl SymbolResolver for Resolver { } .or_else(|| { Python::with_gil(|py| -> PyResult> { - let obj: &PyAny = self.0.module.extract(py)?; + let obj = self.0.module.downcast_bound::(py)?; let mut sym_value: Option<(u64, PyObject)> = None; - let members: &PyDict = obj.getattr("__dict__").unwrap().downcast().unwrap(); + let members = obj.getattr("__dict__").unwrap(); + let members = members.downcast::().unwrap(); for (key, val) in members { let key: &str = key.extract()?; if key == id.to_string() { - let id = self.0.helper.id_fn.call1(py, (val,))?.extract(py)?; + let id = + self.0.helper.id_fn.call1(py, (val.as_borrowed(),))?.extract(py)?; sym_value = Some((id, val.extract()?)); break; } @@ -1548,7 +1599,7 @@ impl SymbolResolver for Resolver { if let Ok(constr) = constraints.get_item(i) { match self.0.get_pyty_obj_type( py, - constr.as_gil_ref(), + constr.as_borrowed(), unifier, defs, primitives,