diff --git a/crates/circuit/src/imports.rs b/crates/circuit/src/imports.rs index b26e8f0b586a..9182530f4a74 100644 --- a/crates/circuit/src/imports.rs +++ b/crates/circuit/src/imports.rs @@ -100,19 +100,28 @@ static STDGATE_IMPORT_PATHS: [[&str; 2]; STANDARD_GATE_SIZE] = [ static mut STDGATE_PYTHON_GATES: GILOnceCell<[Option; STANDARD_GATE_SIZE]> = GILOnceCell::new(); +// A fixed size array is initialized like this because using the `[T; 5]` syntax +// requires T to be `Copy`. But `PyObject` isn't Copy so therefore Option +// as T isn't Copy. +fn _array_of_option_pyobject() -> [Option; STANDARD_GATE_SIZE] { + use std::mem::{self, MaybeUninit}; + let array = unsafe { + let mut data: [MaybeUninit>; STANDARD_GATE_SIZE] = MaybeUninit::uninit().assume_init(); + for elem in &mut data[..] { + *elem = MaybeUninit::new(None); + } + mem::transmute::<_, [Option; STANDARD_GATE_SIZE]>(data) + }; + array +} + #[inline] pub fn populate_std_gate_map(py: Python, rs_gate: StandardGate, py_gate: PyObject) { let gate_map = unsafe { match STDGATE_PYTHON_GATES.get_mut() { Some(gate_map) => gate_map, None => { - // A fixed size array is initialized like this because using the `[T; 5]` syntax - // requires T to be `Copy`. But `PyObject` isn't Copy so therefore Option - // as T isn't Copy. To avoid that we just list out None STANDARD_GATE_SIZE times - let array: [Option; STANDARD_GATE_SIZE] = [ - None, None, None, None, None, None, None, None, None, None, None, None, None, - None, None, None, None, None, None, - ]; + let array = _array_of_option_pyobject(); STDGATE_PYTHON_GATES.set(py, array).unwrap(); STDGATE_PYTHON_GATES.get_mut().unwrap() } @@ -127,16 +136,7 @@ pub fn populate_std_gate_map(py: Python, rs_gate: StandardGate, py_gate: PyObjec #[inline] pub fn get_std_gate_class(py: Python, rs_gate: StandardGate) -> PyResult { let gate_map = unsafe { - STDGATE_PYTHON_GATES.get_or_init(py, || { - // A fixed size array is initialized like this because using the `[T; 5]` syntax - // requires T to be `Copy`. But `PyObject` isn't Copy so therefore Option - // as T isn't Copy. To avoid that we just list out None STANDARD_GATE_SIZE times - let array: [Option; STANDARD_GATE_SIZE] = [ - None, None, None, None, None, None, None, None, None, None, None, None, None, None, - None, None, None, None, None, - ]; - array - }) + STDGATE_PYTHON_GATES.get_or_init(py, _array_of_option_pyobject) }; let gate = &gate_map[rs_gate as usize]; let populate = gate.is_none();